fix(1559): upgrade to Prisma v7 with config restructuring & import updates#1568
fix(1559): upgrade to Prisma v7 with config restructuring & import updates#1568sahilkhude117 wants to merge 5 commits intocredebl:mainfrom
Conversation
Signed-off-by: sahilkhude117 <sahilkhude11@gmail.com>
Signed-off-by: sahilkhude117 <sahilkhude11@gmail.com>
Signed-off-by: sahilkhude117 <sahilkhude11@gmail.com>
Signed-off-by: sahilkhude117 <sahilkhude11@gmail.com>
Signed-off-by: sahilkhude117 <sahilkhude11@gmail.com>
📝 WalkthroughWalkthroughThis pull request refactors the project's Prisma integration by migrating from standard Changes
Estimated code review effort🎯 5 (Critical) | ⏱️ ~105 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Pull request overview
Upgrades the repo to Prisma v7, restructures Prisma configuration to use prisma.config.ts, and refactors the codebase to import the generated Prisma client via the @credebl/prisma alias.
Changes:
- Introduces
prisma.config.tsand updates Prisma schema/client generation output paths. - Adds
@prisma/adapter-pgand updates Prisma client initialization to use the PG adapter. - Refactors numerous imports from
@prisma/clientto@credebl/prisma/client, plus assorted script/path fixes.
Reviewed changes
Copilot reviewed 107 out of 110 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Updates @credebl/prisma/* path mapping to generated Prisma client output. |
| prisma.config.ts | Adds Prisma v7 config file pointing to schema/migrations/seed. |
| pnpm-lock.yaml | Locks Prisma v7 + adapter dependencies; shows remaining Prisma v5 client dependency in workspace. |
| package.json | Adds Prisma PG adapter + bumps Prisma packages; updates Jest moduleNameMapper for new alias. |
| libs/prisma-service/src/prisma-service.service.ts | Initializes PrismaClient with @prisma/adapter-pg adapter. |
| libs/prisma-service/prisma/seed.ts | Updates seed to use generated Prisma client + PG adapter; adjusts data file path. |
| libs/prisma-service/cli.ts | Updates CLI to use PG adapter + generated Prisma client. |
| apps/organization/repositories/organization.repository.ts | Adjusts org_agents relation usage and response shaping. |
| apps/organization/interfaces/organization.interface.ts | Updates Prisma imports/types for Prisma v7 + new generation location. |
| libs/http-exception.filter.ts | Refactors Prisma error imports to new generated/aliased locations. |
| apps/oid4vc-verification/src/oid4vc-verification.module.ts | Renames exported module class. |
| README.md / .env.* / scripts | Updates Prisma-related docs and script paths after restructuring. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "@prisma/adapter-pg": "^7.4.0", | ||
| "@prisma/client": "^7.4.0", |
There was a problem hiding this comment.
Prisma v7 requires Node >=20.19 (see @prisma/client@7.4.0 engines in the lockfile), but this repo still advertises engines.node: >=18. This can lead to installs/builds succeeding on unsupported Node versions and failing at runtime or during prisma generate. Update the root engines (and CI/runtime images) to a Prisma v7-compatible Node version, or pin Prisma to a version that supports your declared Node range.
| const { PrismaPg } = require('@prisma/adapter-pg'); | ||
| const { PrismaClient } = require('generated/prisma/client'); | ||
| const { createClient } = require('@supabase/supabase-js'); |
There was a problem hiding this comment.
require('generated/prisma/client') is a bare module specifier, so Node will try to resolve it from node_modules and this CLI will fail to start. Use a relative path (e.g. ./generated/prisma/client) or the project alias (@credebl/prisma/client) so it resolves correctly.
| const connectionString = process.env.POOL_DATABASE_URL as string; | ||
| const adapter = new PrismaPg({ connectionString }); | ||
|
|
There was a problem hiding this comment.
POOL_DATABASE_URL is asserted as string and used to create the PrismaPg adapter without validation. When running prisma db seed in environments that only provide DATABASE_URL (common for non-pooled connections), this will fail. Consider falling back to DATABASE_URL and/or emitting a clear error if neither is set.
| // Transform org_agents from single object to array to match interface | ||
| if (result && result.org_agents) { | ||
| return { | ||
| ...result, | ||
| org_agents: [result.org_agents] | ||
| } as IGetOrgById; | ||
| } | ||
|
|
||
| // Return with empty array if no org_agents | ||
| return { | ||
| ...result, | ||
| org_agents: [] | ||
| } as IGetOrgById; |
There was a problem hiding this comment.
result from findFirst() can be null. The return { ...result, org_agents: [] } path will throw TypeError: Cannot convert undefined or null to object when no organisation matches. Handle the not-found case explicitly before spreading (e.g., return null, throw NotFoundException, or keep the old findFirstOrThrow).
| import { Prisma } from '@credebl/prisma/client'; | ||
| import { JsonValue } from 'libs/prisma-service/generated/prisma/internal/prismaNamespace'; |
There was a problem hiding this comment.
This import will compile to require('libs/prisma-service/generated/prisma/internal/prismaNamespace'), which Node will treat as a package name and fail to resolve at runtime. Use the established alias (@credebl/prisma/internal/prismaNamespace) or another resolvable module path instead of a non-relative libs/... specifier.
| // direct DB string here (directUrl from old primsa.schema file) | ||
| url: process.env.DATABASE_URL |
There was a problem hiding this comment.
Typo in comment: primsa.schema → prisma.schema.
| '@prisma/client': | ||
| specifier: ^5.1.1 | ||
| version: 5.22.0(prisma@5.22.0) | ||
| version: 5.22.0(prisma@7.4.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.2)) |
There was a problem hiding this comment.
The lockfile still shows libs/common depending on @prisma/client with specifier: ^5.1.1, which results in @prisma/client@5.22.0 being installed alongside Prisma v7. This mix of major versions is risky and can cause type/runtime mismatches; align workspace package versions (and remove the old specifier) so the repo consistently uses Prisma v7.
| import { Catch, ExceptionFilter, HttpException, HttpStatus, Logger } from '@nestjs/common'; | ||
| import { RpcException } from '@nestjs/microservices'; | ||
| import { PrismaClientKnownRequestError, PrismaClientValidationError } from '@prisma/client/runtime/library'; | ||
| import { PrismaClientKnownRequestError, PrismaClientValidationError } from '@credebl/prisma/internal/prismaNamespace'; | ||
| import { Observable, throwError } from 'rxjs'; |
There was a problem hiding this comment.
HttpExceptionFilter does runtime exception.constructor comparisons, so the imported Prisma error symbols must be the real runtime classes. @credebl/prisma/internal/prismaNamespace is typically a types/namespace export, not the Prisma runtime error module; this may cause Prisma errors to fall through to the default case. Prefer importing these from Prisma’s runtime library entry (or another documented runtime export) so the comparisons work reliably.
| constructor() { | ||
| const connectionString = process.env.POOL_DATABASE_URL as string; | ||
| const adapter = new PrismaPg({ connectionString }); | ||
|
|
There was a problem hiding this comment.
POOL_DATABASE_URL is asserted as string and passed into PrismaPg without any validation/fallback. If it’s unset, the adapter/client initialization will throw early with a low-signal error. Prefer an explicit fallback (e.g. DATABASE_URL) and/or throw a clear configuration error when neither env var is set.
| } | ||
| ] | ||
| }) | ||
| export class Oid4vpModule {} | ||
| export class Oid4vcVerificationModule {} |
There was a problem hiding this comment.
The exported module class was renamed to Oid4vcVerificationModule, but apps/oid4vc-verification/src/main.ts still imports/bootstraps Oid4vpModule. This will break compilation/runtime until the main entrypoint is updated to use the new module class name.
There was a problem hiding this comment.
Actionable comments posted: 18
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
apps/user/repositories/user-device.repository.ts (2)
252-257:⚠️ Potential issue | 🟡 MinorPre-existing bug: return type mismatch — SELECT result typed as
BatchPayload.
updateDeviceByCredentialIddeclaresPromise<Prisma.BatchPayload>but executes aSELECT *via$queryRaw, which returns an array of rows, not aBatchPayload. This will silently produce a runtime type mismatch. Consider fixing the return type to match the actual query result (e.g.,Promise<user_devices[]>), and also note the same$queryRawLIKE pattern concern flagged above at Line 150.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/user/repositories/user-device.repository.ts` around lines 252 - 257, The method updateDeviceByCredentialId is declared to return Promise<Prisma.BatchPayload> but calls this.prisma.$queryRaw with a SELECT (user_devices rows), causing a type mismatch; change the return type to match the actual result (e.g., Promise<user_devices[]> or an appropriate DTO/array type) and update callers if needed, and ensure the query uses the correct $queryRaw or $queryRawUnsafe signature on this.prisma.$queryRaw and parameter interpolation for credentialId to avoid SQL injection or LIKE-pattern issues.
150-153:⚠️ Potential issue | 🟠 MajorPre-existing bug:
$queryRawLIKE clause breaks parameterization.This isn't introduced by this PR, but since you're touching this file — the
'%${credentialId}%'inside the tagged template literal doesn't work as intended. Prisma's$queryRawwill parameterize${credentialId}, but wrapping it inside SQL string quotes with%means the resulting SQL becomesLIKE '%$1%', matching the literal text$1rather than the variable's value. This also poses a potential SQL injection risk if it falls back to string concatenation.The correct approach:
Proposed fix
const getUserDevice = await this.prisma.$queryRaw` SELECT * FROM user_devices - WHERE credentialId LIKE '%${credentialId}%' + WHERE "credentialId" LIKE ${'%' + credentialId + '%'} LIMIT 1; `;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/user/repositories/user-device.repository.ts` around lines 150 - 153, The LIKE pattern is currently embedded as a literal string '%${credentialId}%' inside the tagged $queryRaw, which breaks parameterization and risks SQL injection; update the query to supply the pattern as a parameter by concatenating the percent wildcards to credentialId outside the SQL string (e.g., pass ${`%${credentialId}%`} or use CONCAT/|| with ${credentialId}) so the binding stays parameterized—look for the this.prisma.$queryRaw call using credentialId in user-device.repository.ts and replace the '%${credentialId}%' usage with a parameterized pattern.apps/oid4vc-issuance/src/oid4vc-issuance.service.ts (1)
200-201:⚠️ Potential issue | 🔴 CriticalNull-pointer dereference:
&&should be||.If
getIssuerDetailsisnull/undefined, the&&operator evaluates the right-hand side, causing aTypeErrorwhen accessing.publicIssuerIdon a nullish value. This should use||(logical OR) to short-circuit correctly.🐛 Proposed fix
- if (!getIssuerDetails && !getIssuerDetails.publicIssuerId) { + if (!getIssuerDetails || !getIssuerDetails.publicIssuerId) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/oid4vc-issuance/src/oid4vc-issuance.service.ts` around lines 200 - 201, The if condition in oid4vc-issuance.service.ts incorrectly uses && and can throw when getIssuerDetails is nullish; update the check in the block that throws NotFoundException (using ResponseMessages.oidcIssuer.error.notFound) to use || so it short-circuits: i.e., test if (!getIssuerDetails || !getIssuerDetails.publicIssuerId) before throwing; adjust any related null-safe logic in the surrounding method (where getIssuerDetails is used) to match this corrected guard.tsconfig.json (1)
59-70:⚠️ Potential issue | 🟡 MinorRemove or update stale
@credebl/prismabase path mapping.The base alias
"@credebl/prisma"(line 59) maps to"libs/prisma/src", which no longer exists. While no code currently imports from the bare@credebl/prismapath (all imports use wildcards like@credebl/prisma/*), this broken mapping is technical debt. Either remove the alias entirely or update it to point to a valid path inlibs/prisma-service/srcif the base module is still needed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tsconfig.json` around lines 59 - 70, The tsconfig path mapping for the base alias "@credebl/prisma" is stale (it points to "libs/prisma/src" which no longer exists); either remove the "@credebl/prisma" entry from the "paths" block or change its target to a valid location such as "libs/prisma-service/src" (to match the existing "@credebl/prisma/*" wildcard), and ensure the change keeps consistency with "@credebl/prisma/*" and "@credebl/prisma-service" mappings so imports resolve correctly.package.json (1)
25-27:⚠️ Potential issue | 🟡 MinorRemove the
prisma.seedfield from package.json—it is unsupported in Prisma v7 and will be ignored.In Prisma v7, the
"prisma"block in package.json (including"prisma.seed") was removed and is no longer read. The seed configuration must be defined inprisma.config.tsusing themigrations.seedfield, as is already done in this project. Keeping this field creates unnecessary confusion and technical debt.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@package.json` around lines 25 - 27, Remove the legacy Prisma seed entry from package.json: delete the "prisma" object that contains "seed": "ts-node prisma/seed.ts" since Prisma v7 no longer supports package.json seed configuration; rely on the existing prisma.config.ts's migrations.seed instead to avoid confusion and technical debt.
🧹 Nitpick comments (8)
apps/user/repositories/user-device.repository.ts (1)
35-35:String(userId)casts are consistent but worth questioning.If
userIdis already typed asstringin the function signature,String(userId)is a no-op. If there's a runtime concern about receiving non-string values from upstream, a validation/assertion at the service boundary would be cleaner than defensive casting inside every repository method.Also applies to: 55-55, 78-78, 103-103, 122-122
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/user/repositories/user-device.repository.ts` at line 35, The repository uses defensive casts like String(userId) inside UserDeviceRepository methods; remove those casts and pass the typed userId through directly (replace String(userId) with userId) in all occurrences in user-device.repository.ts, and instead add an explicit validation/assertion for userId at the service boundary (e.g., in the UserDeviceService methods that call the repository) to ensure userId is a string (or validate via DTO/schema) before calling repository methods; update any related tests accordingly.apps/api-gateway/src/authz/authz.service.ts (1)
18-22: Two separate imports from the same module can be consolidated.
user(Line 18) andPrisma(Line 21) are both imported from@credebl/prisma/clientin separate statements. Sinceuseris only used as a type annotation (Line 44), it could useimport typeas well. Both could be merged into a single statement.♻️ Optional consolidation
-import { user } from '@credebl/prisma/client'; import { IRestrictedUserSession, ISessionDetails } from 'apps/user/interfaces/user.interface'; -import type { Prisma } from '@credebl/prisma/client'; +import type { Prisma, user } from '@credebl/prisma/client';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api-gateway/src/authz/authz.service.ts` around lines 18 - 22, The imports from "@credebl/prisma/client" are split; consolidate them into a single import and mark type-only imports with "import type" to avoid runtime inclusion: replace the separate imports of "user" and "Prisma" with one statement importing both as types (e.g., import type { user, Prisma } from '@credebl/prisma/client') so references like the type annotation for "user" on the method using IRestrictedUserSession/ISessionDetails are correctly treated as type-only.libs/prisma-service/src/prisma-service.service.ts (1)
32-54: Event listeners registered after$connect— events emitted during connection may be missed.
$on('error', ...),$on('warn', ...), and$on('query', ...)are registered afterawait this.$connect()on line 33. Any log events emitted during the connection phase will be silently dropped. Consider moving the$onregistrations before the$connectcall.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/prisma-service/src/prisma-service.service.ts` around lines 32 - 54, onModuleInit currently calls await this.$connect() before registering Prisma event listeners ($on for 'error','warn','query'), which can miss events emitted during connection; move the (this as any).$on(...) registration blocks for 'error', 'warn', and 'query' to execute before calling await this.$connect(), keeping the same handlers/signatures (Prisma.LogEvent, Prisma.QueryEvent) and then call await this.$connect() so all connection-time events are captured by the existing listeners.libs/prisma-service/prisma/schema.prisma (1)
770-770: Stray blank line insideecosystem_invitationsmodel before the closing@@unique.Line 770 has an empty line between the
userrelation (line 769) and the@@uniqueconstraint (line 771). While not a functional issue, it's inconsistent with the formatting of other models in this schema.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/prisma-service/prisma/schema.prisma` at line 770, In the ecosystem_invitations model remove the stray blank line between the user relation declaration (the line defining the relation field `user`) and the model-level constraint `@@unique` so that the `user` relation and the `@@unique` constraint are adjacent and match the formatting style used by other models; edit the `ecosystem_invitations` model to delete that empty line and ensure spacing matches other model blocks.apps/ledger/src/repositories/ledger.repository.ts (1)
59-109: Duplicatedwhereclause betweenfindManyandcountqueries.The filter condition on lines 69–77 and 88–97 is identical. Extract it to a local variable to avoid drift and reduce duplication.
♻️ Suggested refactor
const { schemaArray, search, pageSize, pageNumber } = data; + const whereClause = { + schemaLedgerId: { + in: schemaArray + }, + OR: [ + { version: { contains: search, mode: 'insensitive' as const } }, + { name: { contains: search, mode: 'insensitive' as const } }, + { schemaLedgerId: { contains: search, mode: 'insensitive' as const } } + ] + }; + const schemasResult: ISchemasResult[] = await this.prisma.schema.findMany({ - where: { - schemaLedgerId: { - in: schemaArray - }, - OR: [ - { version: { contains: search, mode: 'insensitive' } }, - { name: { contains: search, mode: 'insensitive' } }, - { schemaLedgerId: { contains: search, mode: 'insensitive' } } - ] - }, + where: whereClause, take: pageSize, skip: (pageNumber - 1) * pageSize, orderBy: { createDateTime: 'desc' } }); const schemasCount = await this.prisma.schema.count({ - where: { - schemaLedgerId: { - in: schemaArray - }, - OR: [ - { version: { contains: search, mode: 'insensitive' } }, - { name: { contains: search, mode: 'insensitive' } }, - { schemaLedgerId: { contains: search, mode: 'insensitive' } } - ] - } + where: whereClause });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/ledger/src/repositories/ledger.repository.ts` around lines 59 - 109, Extract the duplicated Prisma filter into a local variable inside handleGetSchemas and reuse it for both prisma.schema.findMany and prisma.schema.count: create a const (e.g., schemasWhere) that contains the schemaLedgerId/in array and the OR search clauses, then pass schemasWhere to the where option of the findMany call that returns schemasResult and to the count call that returns schemasCount so the filter logic is defined once and avoids drift between the two queries.apps/ledger/src/schema/schema.controller.ts (1)
68-84: Consider extracting the verbose inline return type to a named interface.This 14-line inline object type makes the method signature harder to read. A dedicated interface (e.g.,
ISchemaExistResult) would improve clarity and be reusable if the same shape is needed elsewhere.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/ledger/src/schema/schema.controller.ts` around lines 68 - 84, The method schemaExist has a long inline return type; extract that object shape to a named interface (e.g., ISchemaExistResult) and use ISchemaExistResult[] as the method's return type. Define the interface with the same properties (id, createDateTime, createdBy, lastChangedDateTime, lastChangedBy, name, version, attributes, schemaLedgerId, publisherDid, issuerId, orgId, ledgerId) near other schema types (or export it from a shared types file) and update schemaExist's signature to return Promise<ISchemaExistResult[]>, keeping exports/visibility consistent with how the file uses interfaces.libs/org-roles/repositories/index.ts (1)
15-40: Missingawaiton the PrismafindManycall ingetAllLedgers-style pattern — but more importantly, inconsistent error handling across methods.
getRole(line 27) andgetOrgRoles(line 38) both thrownew InternalServerErrorException('Bad Request')— the message "Bad Request" is semantically wrong for a 500 status code. Meanwhile,getOrgRolesByIds(line 60) rethrows the original error. This inconsistency predates this PR, but since the methods are being reformatted anyway, it's worth noting for a future cleanup.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/org-roles/repositories/index.ts` around lines 15 - 40, Update error handling to be consistent and accurate: in getRole and getOrgRoles replace the misleading new InternalServerErrorException('Bad Request') with a proper InternalServerErrorException containing contextual text (e.g., 'Failed retrieving org roles' or 'Failed retrieving role') and include or preserve the original error details in the log; ensure getOrgRolesByIds follows the same pattern (log the error via this.logger.error with the error object/stringified and then throw a standardized InternalServerErrorException) so all repository methods (getRole, getOrgRoles, getOrgRolesByIds) uniformly log the original error and throw a clear 500-level exception message.apps/connection/src/connection.service.ts (1)
28-30: Consider consolidating duplicate import statements.Both lines import from the same
@credebl/prisma/clientmodule. They can be merged into a single import.♻️ Proposed consolidation
-import { RecordType, user } from '@credebl/prisma/client'; -import { UserActivityRepository } from 'libs/user-activity/repositories'; -import { agent_invitations } from '@credebl/prisma/client'; +import { RecordType, user, agent_invitations } from '@credebl/prisma/client'; +import { UserActivityRepository } from 'libs/user-activity/repositories';🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/connection/src/connection.service.ts` around lines 28 - 30, Consolidate the duplicate imports from `@credebl/prisma/client` by merging the two import statements into one that imports RecordType, user, and agent_invitations together; update the import block in connection.service.ts to reference these symbols (RecordType, user, agent_invitations) from a single import statement and remove the redundant import so all Prisma types come from one line.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/ecosystem/interfaces/ecosystem.interfaces.ts`:
- Around line 2-5: Remove the non-standard import of JsonValue from
'@credebl/prisma/internal/prismaNamespace' and replace all uses of the
standalone JsonValue type with Prisma.JsonValue, leveraging the already-imported
Prisma symbol (import { Prisma, PrismaClient } ...). Update any interface/type
declarations that reference JsonValue to use Prisma.JsonValue so the file
follows the standard Prisma v7 pattern used elsewhere.
In
`@apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts`:
- Around line 23-45: The saveCredentialDefinition method currently falls through
and returns undefined when getByAttribute finds an existing credential (causing
callers to get NPEs); update saveCredentialDefinition to explicitly handle the
duplicate case by returning the existing credential_definition (dbResult) or by
throwing a clear conflict error (e.g., ConflictError) instead of falling
through—locate saveCredentialDefinition and the getByAttribute call and either
add a return dbResult right after the dbResult check or throw a descriptive
error when dbResult is truthy so callers always receive a defined result or a
controlled exception.
- Around line 102-111: The getByAttribute method swallows errors by logging them
and returning undefined; update credential-definition.repository.ts so async
function getByAttribute(schema: string, tag: string) either re-throws the caught
error (throw error) or returns a rejected Promise after logging, ensuring
callers like saveCredentialDefinition can detect DB failures instead of treating
them as “not found”; specifically modify the catch block in getByAttribute to
include this re-throw behavior and preserve the original error context in the
logger call.
- Around line 171-196: The return type of getAgentType is incorrect: org_agents
is defined as a single optional relation but the method currently types it as an
array; update the Promise return type for getAgentType to reflect that it
returns organisation | null whose org_agents is either (org_agents & {
org_agent_type: org_agents_type }) or null (i.e., Promise<organisation & {
org_agents: (org_agents & { org_agent_type: org_agents_type }) | null } |
null>), and ensure the function signature and any callers/type assertions align
with this corrected type.
In `@apps/ledger/src/ledger.service.ts`:
- Around line 69-81: The null/empty check in schemaDetailsForEcosystem is wrong
because getSchemaDetails is always an object; replace the truthy check with a
check for emptiness (e.g., getSchemaDetails.schemasCount === 0 or
getSchemaDetails.schemasResult?.length === 0) and throw NotFoundException when
empty, and fix the copy-paste logger message by changing the error log from
"Error in getLedgerDetailsById" to "Error in schemaDetailsForEcosystem" (update
the this.logger.error call accordingly).
- Around line 18-31: The current check in getAllLedgers incorrectly treats an
empty array as falsy; update the logic in getAllLedgers to call
this.ledgerRepository.getAllLedgers(), then if the returned array has length ===
0 (e.g., getAllLedgerDetails.length === 0) throw the
NotFoundException(ResponseMessages.ledger.error.NotFound); otherwise return the
array; keep the catch block but ensure the thrown RpcException still forwards
the original error/response as before.
In `@apps/ledger/src/repositories/ledger.repository.ts`:
- Around line 15-22: The try/catch blocks in getAllLedgers, getNetworkUrl, and
getNetworkById are ineffective because the Prisma calls
(this.prisma.ledgers.findMany, this.prisma.networks.findFirst,
this.prisma.networks.findUnique) return Promises that are returned without
awaiting, so add await before each Prisma call so errors are thrown inside the
try block and caught by the existing this.logger.error/throw error handling;
ensure the methods remain async and keep the same log messages (e.g., in
getAllLedgers, getNetworkUrl, getNetworkById) so runtime exceptions are properly
logged and rethrown.
In `@apps/oid4vc-verification/src/oid4vc-verification.module.ts`:
- Line 52: The bootstrap in main.ts still imports/uses the old Oid4vpModule;
update the import statement to import Oid4vcVerificationModule and change the
Nest application creation to use Oid4vcVerificationModule (replace any remaining
Oid4vpModule references with Oid4vcVerificationModule) so the module class name
matches the renamed export.
In `@apps/organization/interfaces/organization.interface.ts`:
- Around line 1-2: Remove the fragile internal import of JsonValue and replace
its usage with the Prisma-provided type: delete the import "JsonValue" from
'libs/prisma-service/generated/prisma/internal/prismaNamespace' and change the
standalone JsonValue type reference (the usage at the position currently noted
on line 287) to Prisma.JsonValue; also remove the now-unused JsonValue import so
only the existing import { Prisma } from '@credebl/prisma/client' remains and
other references to Prisma.JsonValue (as seen elsewhere in the file) stay
consistent.
In `@apps/organization/repositories/organization.repository.ts`:
- Around line 508-521: The code assumes result from findFirst is non-null and
spreads it, which corrupts IGetOrgById when result === null; update the
getOrganization implementation to check "if (!result) return null;" before any
spreading or org_agents manipulation, keep transforming result.org_agents to an
array only when result exists, change the getOrganization return type to
Promise<IGetOrgById | null>, and audit callers of getOrganization to handle the
null case; references: findFirst, getOrganization, IGetOrgById, and org_agents.
In `@apps/user/repositories/fido-user.repository.ts`:
- Around line 112-118: Change the updateUserDetails signature to accept a single
UserUpdateData (not UserUpdateData[]): updateUserDetails(email: string,
additionalParams: UserUpdateData): Promise<user>; update the prisma update call
to spread additionalParams directly (data: { ...additionalParams }) and add a
guard/validation so additionalParams cannot be undefined before spreading; then
update the three call sites in the Fido service that currently pass a
single-element array to pass the object itself (remove the surrounding [ ... ]).
Ensure all types/imports reflect UserUpdateData (not array).
In `@libs/http-exception.filter.ts`:
- Line 3: Replace the incorrect internal import and fragile constructor-based
checks: change the import to "import { Prisma } from '@credebl/prisma/client';"
and in the error handling replace the switch(exception.constructor) logic with
instanceof checks using Prisma.PrismaClientKnownRequestError and
Prisma.PrismaClientValidationError (e.g., if (exception instanceof
Prisma.PrismaClientKnownRequestError) { ... } else if (exception instanceof
Prisma.PrismaClientValidationError) { ... }) to reliably detect Prisma errors at
runtime.
In `@libs/prisma-service/cli.ts`:
- Line 9: The require call in cli.ts is using a non-relative module specifier
and will fail at runtime; update the import for Prisma to use a relative path by
changing the require used to populate const { PrismaClient } to point to the
local generated client (use a ./ prefix like the other files do) so Node
resolves it from the package root rather than node_modules.
In `@libs/prisma-service/prisma/schema.prisma`:
- Line 612: The id fields on the credential_templates and x509_certificates
models are defined as String `@id` `@default`(uuid()) but are missing the `@db.Uuid`
attribute; update those fields to include `@db.Uuid` so the database column uses
PostgreSQL's native uuid type (e.g., change the credential_templates.id and
x509_certificates.id declarations to String `@id` `@default`(uuid()) `@db.Uuid`) to
make them consistent with other UUID primary keys and efficient for
indexing/joins.
In `@libs/prisma-service/prisma/seed.ts`:
- Around line 15-16: The code in seed.ts uses process.env.POOL_DATABASE_URL
directly causing a crash if unset; change the connectionString assignment to
fall back to process.env.DATABASE_URL (same behavior as cli.ts) and add a guard
that throws a clear error if neither is present before instantiating new
PrismaPg({ connectionString }); specifically update the connectionString
variable lookup and ensure the PrismaPg adapter creation is only attempted after
verifying connectionString is non-empty.
In `@libs/prisma-service/src/prisma-service.service.ts`:
- Around line 14-15: The code reads process.env.POOL_DATABASE_URL into
connectionString and passes it to new PrismaPg without the fallback used in
cli.ts, so replace the direct read with the same fallback logic (use
process.env.POOL_DATABASE_URL || process.env.DATABASE_URL) when constructing
connectionString for PrismaPg and add a simple validation that throws or logs a
descriptive error if the resulting connectionString is still missing; update the
usage around the PrismaPg instantiation (the connectionString variable and the
new PrismaPg({ connectionString }) call) to use the fallback and validation.
In `@libs/user-org-roles/src/user-org-roles.service.ts`:
- Around line 52-54: The loop is calling
userOrgRoleRepository.createUserOrgRole(...) without awaiting the returned
Promise, causing fire-and-forget writes and unhandled rejections; fix by
awaiting the calls: either change the for-loop to await each createUserOrgRole
call (sequential) or map roleIdList to an array of Promises via
userOrgRoleRepository.createUserOrgRole(...) and await Promise.all(...)
(parallel), ensuring the surrounding function is async and propagates or handles
rejections.
In `@prisma.config.ts`:
- Line 11: Fix the typo in the inline comment that reads "direct DB string here
(directUrl from old primsa.schema file)" by changing "primsa" to "prisma" so it
reads "...(directUrl from old prisma.schema file)"; update the comment near the
direct DB string placeholder to correct the misspelling.
---
Outside diff comments:
In `@apps/oid4vc-issuance/src/oid4vc-issuance.service.ts`:
- Around line 200-201: The if condition in oid4vc-issuance.service.ts
incorrectly uses && and can throw when getIssuerDetails is nullish; update the
check in the block that throws NotFoundException (using
ResponseMessages.oidcIssuer.error.notFound) to use || so it short-circuits:
i.e., test if (!getIssuerDetails || !getIssuerDetails.publicIssuerId) before
throwing; adjust any related null-safe logic in the surrounding method (where
getIssuerDetails is used) to match this corrected guard.
In `@apps/user/repositories/user-device.repository.ts`:
- Around line 252-257: The method updateDeviceByCredentialId is declared to
return Promise<Prisma.BatchPayload> but calls this.prisma.$queryRaw with a
SELECT (user_devices rows), causing a type mismatch; change the return type to
match the actual result (e.g., Promise<user_devices[]> or an appropriate
DTO/array type) and update callers if needed, and ensure the query uses the
correct $queryRaw or $queryRawUnsafe signature on this.prisma.$queryRaw and
parameter interpolation for credentialId to avoid SQL injection or LIKE-pattern
issues.
- Around line 150-153: The LIKE pattern is currently embedded as a literal
string '%${credentialId}%' inside the tagged $queryRaw, which breaks
parameterization and risks SQL injection; update the query to supply the pattern
as a parameter by concatenating the percent wildcards to credentialId outside
the SQL string (e.g., pass ${`%${credentialId}%`} or use CONCAT/|| with
${credentialId}) so the binding stays parameterized—look for the
this.prisma.$queryRaw call using credentialId in user-device.repository.ts and
replace the '%${credentialId}%' usage with a parameterized pattern.
In `@package.json`:
- Around line 25-27: Remove the legacy Prisma seed entry from package.json:
delete the "prisma" object that contains "seed": "ts-node prisma/seed.ts" since
Prisma v7 no longer supports package.json seed configuration; rely on the
existing prisma.config.ts's migrations.seed instead to avoid confusion and
technical debt.
In `@tsconfig.json`:
- Around line 59-70: The tsconfig path mapping for the base alias
"@credebl/prisma" is stale (it points to "libs/prisma/src" which no longer
exists); either remove the "@credebl/prisma" entry from the "paths" block or
change its target to a valid location such as "libs/prisma-service/src" (to
match the existing "@credebl/prisma/*" wildcard), and ensure the change keeps
consistency with "@credebl/prisma/*" and "@credebl/prisma-service" mappings so
imports resolve correctly.
---
Nitpick comments:
In `@apps/api-gateway/src/authz/authz.service.ts`:
- Around line 18-22: The imports from "@credebl/prisma/client" are split;
consolidate them into a single import and mark type-only imports with "import
type" to avoid runtime inclusion: replace the separate imports of "user" and
"Prisma" with one statement importing both as types (e.g., import type { user,
Prisma } from '@credebl/prisma/client') so references like the type annotation
for "user" on the method using IRestrictedUserSession/ISessionDetails are
correctly treated as type-only.
In `@apps/connection/src/connection.service.ts`:
- Around line 28-30: Consolidate the duplicate imports from
`@credebl/prisma/client` by merging the two import statements into one that
imports RecordType, user, and agent_invitations together; update the import
block in connection.service.ts to reference these symbols (RecordType, user,
agent_invitations) from a single import statement and remove the redundant
import so all Prisma types come from one line.
In `@apps/ledger/src/repositories/ledger.repository.ts`:
- Around line 59-109: Extract the duplicated Prisma filter into a local variable
inside handleGetSchemas and reuse it for both prisma.schema.findMany and
prisma.schema.count: create a const (e.g., schemasWhere) that contains the
schemaLedgerId/in array and the OR search clauses, then pass schemasWhere to the
where option of the findMany call that returns schemasResult and to the count
call that returns schemasCount so the filter logic is defined once and avoids
drift between the two queries.
In `@apps/ledger/src/schema/schema.controller.ts`:
- Around line 68-84: The method schemaExist has a long inline return type;
extract that object shape to a named interface (e.g., ISchemaExistResult) and
use ISchemaExistResult[] as the method's return type. Define the interface with
the same properties (id, createDateTime, createdBy, lastChangedDateTime,
lastChangedBy, name, version, attributes, schemaLedgerId, publisherDid,
issuerId, orgId, ledgerId) near other schema types (or export it from a shared
types file) and update schemaExist's signature to return
Promise<ISchemaExistResult[]>, keeping exports/visibility consistent with how
the file uses interfaces.
In `@apps/user/repositories/user-device.repository.ts`:
- Line 35: The repository uses defensive casts like String(userId) inside
UserDeviceRepository methods; remove those casts and pass the typed userId
through directly (replace String(userId) with userId) in all occurrences in
user-device.repository.ts, and instead add an explicit validation/assertion for
userId at the service boundary (e.g., in the UserDeviceService methods that call
the repository) to ensure userId is a string (or validate via DTO/schema) before
calling repository methods; update any related tests accordingly.
In `@libs/org-roles/repositories/index.ts`:
- Around line 15-40: Update error handling to be consistent and accurate: in
getRole and getOrgRoles replace the misleading new
InternalServerErrorException('Bad Request') with a proper
InternalServerErrorException containing contextual text (e.g., 'Failed
retrieving org roles' or 'Failed retrieving role') and include or preserve the
original error details in the log; ensure getOrgRolesByIds follows the same
pattern (log the error via this.logger.error with the error object/stringified
and then throw a standardized InternalServerErrorException) so all repository
methods (getRole, getOrgRoles, getOrgRolesByIds) uniformly log the original
error and throw a clear 500-level exception message.
In `@libs/prisma-service/prisma/schema.prisma`:
- Line 770: In the ecosystem_invitations model remove the stray blank line
between the user relation declaration (the line defining the relation field
`user`) and the model-level constraint `@@unique` so that the `user` relation
and the `@@unique` constraint are adjacent and match the formatting style used
by other models; edit the `ecosystem_invitations` model to delete that empty
line and ensure spacing matches other model blocks.
In `@libs/prisma-service/src/prisma-service.service.ts`:
- Around line 32-54: onModuleInit currently calls await this.$connect() before
registering Prisma event listeners ($on for 'error','warn','query'), which can
miss events emitted during connection; move the (this as any).$on(...)
registration blocks for 'error', 'warn', and 'query' to execute before calling
await this.$connect(), keeping the same handlers/signatures (Prisma.LogEvent,
Prisma.QueryEvent) and then call await this.$connect() so all connection-time
events are captured by the existing listeners.
| import { Prisma, PrismaClient } from '@credebl/prisma/client'; | ||
|
|
||
| import { CommonTableColumns } from '@credebl/common/interfaces/interface'; | ||
| import { JsonValue } from '@prisma/client/runtime/library'; | ||
| import { JsonValue } from '@credebl/prisma/internal/prismaNamespace'; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
rg -n "JsonValue" --type=ts -C2Repository: credebl/platform
Length of output: 11733
🏁 Script executed:
fd "prismaNamespace" --type fRepository: credebl/platform
Length of output: 42
🏁 Script executed:
find . -type f -name "*.ts" | xargs grep -l "@credebl/prisma" | head -20Repository: credebl/platform
Length of output: 1478
🌐 Web query:
Prisma v7 JsonValue import source
💡 Result:
In Prisma v7, JsonValue comes from the Prisma namespace in @prisma/client:
import type { Prisma } from '@prisma/client';
type X = Prisma.JsonValue;This is the documented/public pattern for JSON helper types like Prisma.JsonArray / Prisma.JsonObject / Prisma.JsonValue. [1] (Example usage: import { Prisma } from "@prisma/client" then Prisma.JsonValue.) [2]
If you specifically want a direct type import, some projects import it from:
import type { JsonValue } from '@prisma/client/runtime/library';…but Prisma considers @prisma/client/runtime/* a private API (no backward-compat guarantees). [3] [4]
Sources: [1] [2] [3] [4]
Replace the custom JsonValue import with the standard Prisma pattern.
The import from @credebl/prisma/internal/prismaNamespace is non-standard and inconsistent with how JsonValue is used throughout the codebase. Prisma v7 exposes JsonValue via the Prisma namespace, which you already import on line 2. Use Prisma.JsonValue instead:
// Current (line 5)
import { JsonValue } from '@credebl/prisma/internal/prismaNamespace';
// Replace with usage of existing Prisma import
// Then use: Prisma.JsonValue in the interface (line 182)This aligns with the standard pattern used in 15+ other files across the codebase (e.g., apps/user/repositories/user-device.repository.ts, apps/agent-service/src/interface/agent-service.interface.ts).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/ecosystem/interfaces/ecosystem.interfaces.ts` around lines 2 - 5, Remove
the non-standard import of JsonValue from
'@credebl/prisma/internal/prismaNamespace' and replace all uses of the
standalone JsonValue type with Prisma.JsonValue, leveraging the already-imported
Prisma symbol (import { Prisma, PrismaClient } ...). Update any interface/type
declarations that reference JsonValue to use Prisma.JsonValue so the file
follows the standard Prisma v7 pattern used elsewhere.
| async saveCredentialDefinition(credDef: CredDefPayload): Promise<credential_definition> { | ||
| try { | ||
| const dbResult: credential_definition = await this.getByAttribute(credDef.schemaLedgerId, credDef.tag); | ||
| if (!dbResult) { | ||
| const saveResult = await this.prisma.credential_definition.create({ | ||
| data: { | ||
| schemaLedgerId: credDef.schemaLedgerId, | ||
| tag: credDef.tag, | ||
| credentialDefinitionId: credDef.credentialDefinitionId, | ||
| revocable: credDef.revocable, | ||
| createdBy: credDef.createdBy, | ||
| lastChangedBy: credDef.lastChangedBy, | ||
| orgId: credDef.orgId, | ||
| schemaId: credDef.schemaId | ||
| } | ||
| }); | ||
| return saveResult; | ||
| } | ||
| } catch (error) { | ||
| this.logger.error(`${ResponseMessages.credentialDefinition.error.NotSaved}: ${error.message} `); | ||
| throw error; | ||
| } | ||
| } |
There was a problem hiding this comment.
saveCredentialDefinition silently returns undefined when a duplicate exists.
If getByAttribute finds an existing record, execution falls through the if (!dbResult) block with no return value. Callers that expect a credential_definition object will receive undefined, which can cause downstream NPEs.
Consider explicitly returning the existing record or throwing a conflict error:
Proposed fix
async saveCredentialDefinition(credDef: CredDefPayload): Promise<credential_definition> {
try {
const dbResult: credential_definition = await this.getByAttribute(credDef.schemaLedgerId, credDef.tag);
if (!dbResult) {
const saveResult = await this.prisma.credential_definition.create({
...
});
return saveResult;
}
+ return dbResult;
} catch (error) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async saveCredentialDefinition(credDef: CredDefPayload): Promise<credential_definition> { | |
| try { | |
| const dbResult: credential_definition = await this.getByAttribute(credDef.schemaLedgerId, credDef.tag); | |
| if (!dbResult) { | |
| const saveResult = await this.prisma.credential_definition.create({ | |
| data: { | |
| schemaLedgerId: credDef.schemaLedgerId, | |
| tag: credDef.tag, | |
| credentialDefinitionId: credDef.credentialDefinitionId, | |
| revocable: credDef.revocable, | |
| createdBy: credDef.createdBy, | |
| lastChangedBy: credDef.lastChangedBy, | |
| orgId: credDef.orgId, | |
| schemaId: credDef.schemaId | |
| } | |
| }); | |
| return saveResult; | |
| } | |
| } catch (error) { | |
| this.logger.error(`${ResponseMessages.credentialDefinition.error.NotSaved}: ${error.message} `); | |
| throw error; | |
| } | |
| } | |
| async saveCredentialDefinition(credDef: CredDefPayload): Promise<credential_definition> { | |
| try { | |
| const dbResult: credential_definition = await this.getByAttribute(credDef.schemaLedgerId, credDef.tag); | |
| if (!dbResult) { | |
| const saveResult = await this.prisma.credential_definition.create({ | |
| data: { | |
| schemaLedgerId: credDef.schemaLedgerId, | |
| tag: credDef.tag, | |
| credentialDefinitionId: credDef.credentialDefinitionId, | |
| revocable: credDef.revocable, | |
| createdBy: credDef.createdBy, | |
| lastChangedBy: credDef.lastChangedBy, | |
| orgId: credDef.orgId, | |
| schemaId: credDef.schemaId | |
| } | |
| }); | |
| return saveResult; | |
| } | |
| return dbResult; | |
| } catch (error) { | |
| this.logger.error(`${ResponseMessages.credentialDefinition.error.NotSaved}: ${error.message} `); | |
| throw error; | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts`
around lines 23 - 45, The saveCredentialDefinition method currently falls
through and returns undefined when getByAttribute finds an existing credential
(causing callers to get NPEs); update saveCredentialDefinition to explicitly
handle the duplicate case by returning the existing credential_definition
(dbResult) or by throwing a clear conflict error (e.g., ConflictError) instead
of falling through—locate saveCredentialDefinition and the getByAttribute call
and either add a return dbResult right after the dbResult check or throw a
descriptive error when dbResult is truthy so callers always receive a defined
result or a controlled exception.
| async getByAttribute(schema: string, tag: string): Promise<credential_definition> { | ||
| try { | ||
| const response = await this.prisma.credential_definition.findFirst({ | ||
| where: { schemaLedgerId: schema, tag: { contains: tag, mode: 'insensitive' } } | ||
| }); | ||
| return response; | ||
| } catch (error) { | ||
| this.logger.error(`${ResponseMessages.credentialDefinition.error.NotFound}: ${error}`); | ||
| } | ||
| } |
There was a problem hiding this comment.
getByAttribute swallows errors — catch block doesn't re-throw.
The catch block logs the error but doesn't throw, so any Prisma query failure silently returns undefined. This masks database errors and makes saveCredentialDefinition (which depends on this method) believe no existing record was found, potentially leading to duplicate creation attempts or constraint violations.
Proposed fix
} catch (error) {
this.logger.error(`${ResponseMessages.credentialDefinition.error.NotFound}: ${error}`);
+ throw error;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async getByAttribute(schema: string, tag: string): Promise<credential_definition> { | |
| try { | |
| const response = await this.prisma.credential_definition.findFirst({ | |
| where: { schemaLedgerId: schema, tag: { contains: tag, mode: 'insensitive' } } | |
| }); | |
| return response; | |
| } catch (error) { | |
| this.logger.error(`${ResponseMessages.credentialDefinition.error.NotFound}: ${error}`); | |
| } | |
| } | |
| async getByAttribute(schema: string, tag: string): Promise<credential_definition> { | |
| try { | |
| const response = await this.prisma.credential_definition.findFirst({ | |
| where: { schemaLedgerId: schema, tag: { contains: tag, mode: 'insensitive' } } | |
| }); | |
| return response; | |
| } catch (error) { | |
| this.logger.error(`${ResponseMessages.credentialDefinition.error.NotFound}: ${error}`); | |
| throw error; | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts`
around lines 102 - 111, The getByAttribute method swallows errors by logging
them and returning undefined; update credential-definition.repository.ts so
async function getByAttribute(schema: string, tag: string) either re-throws the
caught error (throw error) or returns a rejected Promise after logging, ensuring
callers like saveCredentialDefinition can detect DB failures instead of treating
them as “not found”; specifically modify the catch block in getByAttribute to
include this re-throw behavior and preserve the original error context in the
logger call.
| async getAgentType(orgId: string): Promise< | ||
| organisation & { | ||
| org_agents: (org_agents & { | ||
| org_agent_type: org_agents_type; | ||
| })[]; | ||
| } | ||
| > { | ||
| try { | ||
| const agentDetails = await this.prisma.organisation.findUnique({ | ||
| where: { | ||
| id: orgId | ||
| }, | ||
| include: { | ||
| org_agents: { | ||
| include: { | ||
| org_agent_type: true | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| return agentDetails; | ||
| } catch (error) { | ||
| this.logger.error(`Error in getting agent type: ${error}`); | ||
| throw error; | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd "schema.prisma" --type fRepository: credebl/platform
Length of output: 100
🏁 Script executed:
cat libs/prisma-service/prisma/schema.prisma | grep -B5 -A10 "model org_agents"Repository: credebl/platform
Length of output: 1362
🏁 Script executed:
cat libs/prisma-service/prisma/schema.prisma | grep -B2 -A20 "^model organisation"Repository: credebl/platform
Length of output: 1238
🏁 Script executed:
cat libs/prisma-service/prisma/schema.prisma | grep -A100 "^model organisation" | grep -B2 -A2 "org_agents"Repository: credebl/platform
Length of output: 508
Fix return type of getAgentType — org_agents is a single optional object, not an array.
The Prisma schema defines org_agents as org_agents? (single optional relation), but the return type annotates it as an array: org_agents[]. Since the query uses findUnique with a single org_agents include, Prisma returns a single object or null, not an array. Update the return type to reflect this:
Promise<
organisation & {
org_agents: (org_agents & {
org_agent_type: org_agents_type;
}) | null;
} | null
>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@apps/ledger/src/credential-definition/repositories/credential-definition.repository.ts`
around lines 171 - 196, The return type of getAgentType is incorrect: org_agents
is defined as a single optional relation but the method currently types it as an
array; update the Promise return type for getAgentType to reflect that it
returns organisation | null whose org_agents is either (org_agents & {
org_agent_type: org_agents_type }) or null (i.e., Promise<organisation & {
org_agents: (org_agents & { org_agent_type: org_agents_type }) | null } |
null>), and ensure the function signature and any callers/type assertions align
with this corrected type.
| async getAllLedgers(): Promise<ledgers[]> { | ||
| try { | ||
| const getAllLedgerDetails = await this.ledgerRepository.getAllLedgers(); | ||
|
|
||
| if (!getAllLedgerDetails) { | ||
| throw new NotFoundException(ResponseMessages.ledger.error.NotFound); | ||
| } | ||
|
|
||
| return getAllLedgerDetails; | ||
| } catch (error) { | ||
| this.logger.error(`Error in retrieving all ledgers: ${error}`); | ||
| throw new RpcException(error.response ? error.response : error); | ||
| } | ||
| } |
There was a problem hiding this comment.
!getAllLedgerDetails will never be falsy — findMany returns [], not null.
Prisma's findMany always returns an array (empty if no results). The check !getAllLedgerDetails on line 22 will never trigger because an empty array is truthy. If the intent is to throw when no ledgers exist, check the array length instead.
🐛 Proposed fix
- if (!getAllLedgerDetails) {
+ if (0 === getAllLedgerDetails.length) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async getAllLedgers(): Promise<ledgers[]> { | |
| try { | |
| const getAllLedgerDetails = await this.ledgerRepository.getAllLedgers(); | |
| if (!getAllLedgerDetails) { | |
| throw new NotFoundException(ResponseMessages.ledger.error.NotFound); | |
| } | |
| return getAllLedgerDetails; | |
| } catch (error) { | |
| this.logger.error(`Error in retrieving all ledgers: ${error}`); | |
| throw new RpcException(error.response ? error.response : error); | |
| } | |
| } | |
| async getAllLedgers(): Promise<ledgers[]> { | |
| try { | |
| const getAllLedgerDetails = await this.ledgerRepository.getAllLedgers(); | |
| if (0 === getAllLedgerDetails.length) { | |
| throw new NotFoundException(ResponseMessages.ledger.error.NotFound); | |
| } | |
| return getAllLedgerDetails; | |
| } catch (error) { | |
| this.logger.error(`Error in retrieving all ledgers: ${error}`); | |
| throw new RpcException(error.response ? error.response : error); | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/ledger/src/ledger.service.ts` around lines 18 - 31, The current check in
getAllLedgers incorrectly treats an empty array as falsy; update the logic in
getAllLedgers to call this.ledgerRepository.getAllLedgers(), then if the
returned array has length === 0 (e.g., getAllLedgerDetails.length === 0) throw
the NotFoundException(ResponseMessages.ledger.error.NotFound); otherwise return
the array; keep the catch block but ensure the thrown RpcException still
forwards the original error/response as before.
|
|
||
| model credential_templates { | ||
| id String @id @default(uuid()) | ||
| id String @id @default(uuid()) |
There was a problem hiding this comment.
Missing @db.Uuid on credential_templates.id and x509_certificates.id.
Nearly every other UUID primary key in this schema uses @db.Uuid to store the value as a native PostgreSQL uuid type. These two models use @id @default(uuid()) without @db.Uuid, which means the column will be stored as text — inconsistent with the rest of the schema and less efficient for indexing/joins.
🐛 Proposed fix
model credential_templates {
- id String `@id` `@default`(uuid())
+ id String `@id` `@default`(uuid()) `@db.Uuid`
name String model x509_certificates {
- id String `@id` `@default`(uuid())
+ id String `@id` `@default`(uuid()) `@db.Uuid`
orgAgentId String `@db.Uuid`Also applies to: 627-627
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/prisma-service/prisma/schema.prisma` at line 612, The id fields on the
credential_templates and x509_certificates models are defined as String `@id`
`@default`(uuid()) but are missing the `@db.Uuid` attribute; update those fields to
include `@db.Uuid` so the database column uses PostgreSQL's native uuid type
(e.g., change the credential_templates.id and x509_certificates.id declarations
to String `@id` `@default`(uuid()) `@db.Uuid`) to make them consistent with other UUID
primary keys and efficient for indexing/joins.
| const connectionString = process.env.POOL_DATABASE_URL as string; | ||
| const adapter = new PrismaPg({ connectionString }); |
There was a problem hiding this comment.
Missing fallback for POOL_DATABASE_URL — same issue as in prisma-service.service.ts.
Unlike cli.ts which falls back to DATABASE_URL, this file will fail with an opaque error if POOL_DATABASE_URL is unset. Consider adding a fallback and/or a guard, consistent with cli.ts line 13.
Suggested fix
-const connectionString = process.env.POOL_DATABASE_URL as string;
+const connectionString = (process.env.POOL_DATABASE_URL || process.env.DATABASE_URL) as string;
+if (!connectionString) {
+ throw new Error('Neither POOL_DATABASE_URL nor DATABASE_URL is set');
+}
const adapter = new PrismaPg({ connectionString });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const connectionString = process.env.POOL_DATABASE_URL as string; | |
| const adapter = new PrismaPg({ connectionString }); | |
| const connectionString = (process.env.POOL_DATABASE_URL || process.env.DATABASE_URL) as string; | |
| if (!connectionString) { | |
| throw new Error('Neither POOL_DATABASE_URL nor DATABASE_URL is set'); | |
| } | |
| const adapter = new PrismaPg({ connectionString }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/prisma-service/prisma/seed.ts` around lines 15 - 16, The code in seed.ts
uses process.env.POOL_DATABASE_URL directly causing a crash if unset; change the
connectionString assignment to fall back to process.env.DATABASE_URL (same
behavior as cli.ts) and add a guard that throws a clear error if neither is
present before instantiating new PrismaPg({ connectionString }); specifically
update the connectionString variable lookup and ensure the PrismaPg adapter
creation is only attempted after verifying connectionString is non-empty.
| const connectionString = process.env.POOL_DATABASE_URL as string; | ||
| const adapter = new PrismaPg({ connectionString }); |
There was a problem hiding this comment.
Missing fallback for POOL_DATABASE_URL — inconsistent with cli.ts.
cli.ts (line 13) uses process.env.POOL_DATABASE_URL || process.env.DATABASE_URL as a fallback, but here POOL_DATABASE_URL is read without any fallback. If the variable is unset, connectionString will be undefined (cast away by as string), and PrismaPg will throw an opaque error at runtime.
Suggested fix
- const connectionString = process.env.POOL_DATABASE_URL as string;
- const adapter = new PrismaPg({ connectionString });
+ const connectionString = process.env.POOL_DATABASE_URL || process.env.DATABASE_URL;
+ if (!connectionString) {
+ throw new Error('Neither POOL_DATABASE_URL nor DATABASE_URL is set');
+ }
+ const adapter = new PrismaPg({ connectionString });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const connectionString = process.env.POOL_DATABASE_URL as string; | |
| const adapter = new PrismaPg({ connectionString }); | |
| const connectionString = process.env.POOL_DATABASE_URL || process.env.DATABASE_URL; | |
| if (!connectionString) { | |
| throw new Error('Neither POOL_DATABASE_URL nor DATABASE_URL is set'); | |
| } | |
| const adapter = new PrismaPg({ connectionString }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/prisma-service/src/prisma-service.service.ts` around lines 14 - 15, The
code reads process.env.POOL_DATABASE_URL into connectionString and passes it to
new PrismaPg without the fallback used in cli.ts, so replace the direct read
with the same fallback logic (use process.env.POOL_DATABASE_URL ||
process.env.DATABASE_URL) when constructing connectionString for PrismaPg and
add a simple validation that throws or logs a descriptive error if the resulting
connectionString is still missing; update the usage around the PrismaPg
instantiation (the connectionString variable and the new PrismaPg({
connectionString }) call) to use the fallback and validation.
| for (const roleData of roleIdList) { | ||
| this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId); | ||
| } |
There was a problem hiding this comment.
Missing await on async repository call — promises are fire-and-forget.
createUserOrgRole returns a Promise, but the call is not awaited. This means:
- The function returns
truebefore any DB writes complete. - Rejected promises are silently swallowed (unhandled rejection).
- Callers cannot rely on the return value to confirm roles were actually created.
🐛 Proposed fix
for (const roleData of roleIdList) {
- this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId);
+ await this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId);
}If the writes are independent and you want parallelism:
- for (const roleData of roleIdList) {
- this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId);
- }
+ await Promise.all(
+ roleIdList.map((roleData) =>
+ this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId)
+ )
+ );📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for (const roleData of roleIdList) { | |
| this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId); | |
| } | |
| for (const roleData of roleIdList) { | |
| await this.userOrgRoleRepository.createUserOrgRole(userId, roleData.roleId, orgId, roleData.idpRoleId); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/user-org-roles/src/user-org-roles.service.ts` around lines 52 - 54, The
loop is calling userOrgRoleRepository.createUserOrgRole(...) without awaiting
the returned Promise, causing fire-and-forget writes and unhandled rejections;
fix by awaiting the calls: either change the for-loop to await each
createUserOrgRole call (sequential) or map roleIdList to an array of Promises
via userOrgRoleRepository.createUserOrgRole(...) and await Promise.all(...)
(parallel), ensuring the surrounding function is async and propagates or handles
rejections.
| seed: 'ts-node libs/prisma-service/prisma/seed.ts' | ||
| }, | ||
| datasource: { | ||
| // direct DB string here (directUrl from old primsa.schema file) |
There was a problem hiding this comment.
Typo in comment: "primsa" → "prisma".
- // direct DB string here (directUrl from old primsa.schema file)
+ // direct DB string here (directUrl from old prisma.schema file)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // direct DB string here (directUrl from old primsa.schema file) | |
| // direct DB string here (directUrl from old prisma.schema file) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@prisma.config.ts` at line 11, Fix the typo in the inline comment that reads
"direct DB string here (directUrl from old primsa.schema file)" by changing
"primsa" to "prisma" so it reads "...(directUrl from old prisma.schema file)";
update the comment near the direct DB string placeholder to correct the
misspelling.



This PR upgrades the project to Prisma v7 and applies all required structural, configuration, client, seed, and import updates.
Main Changes
Core Prisma Upgrade
prisma.config.tsschema.prismaREADME.mdPrisma Client Adjustments
cli.tsprisma-service.service.tsSeed & Script Fixes
seed.tsscripts/geo_location_data_import.sh.env.demo.env.sampleImport & Module Refactoring
package.jsoni.e@credebl/prismaforlibs/prisma-service/generated/prismato easily import client. with@credebl/prisma/client.tsconfig.jsonpaths configuration@primsa/clientto@credebl/prisma/client(which maps tolibs/prisma-service/generated/prisma/client)Summary by CodeRabbit