Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the codebase to consolidate request handling by introducing a unified requests collection system with support for header delta compression. The changes rename "UserCommitment" types to "ImageCaptcha" for clarity and merge pending request handling into the main image captcha schema.
Changes:
- Introduced unified requests collection with header delta compression capabilities
- Renamed UserCommitment types to ImageCaptcha throughout the codebase
- Merged pending captcha request functionality into ImageCaptcha schema
- Added database methods for the new unified requests collection
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/types-database/src/utils/headerDelta.ts | New utility for calculating header deltas and estimating storage savings |
| packages/types-database/src/types/request.ts | New unified request types and schemas with support for session, PoW, and image captcha requests |
| packages/types-database/src/types/provider.ts | Renamed UserCommitment to ImageCaptcha, merged pending fields, added unified requests methods |
| packages/types-database/src/types/index.ts | Exported new request types |
| packages/types-database/src/types/captcha.ts | Updated to use ImageCaptcha types instead of UserCommitment |
| packages/types-database/src/index.ts | Exported header delta utilities |
| packages/provider/src/tests/unit/tasks/imgCaptcha/imgCaptchaTasks.unit.test.ts | Updated tests to use new ImageCaptcha types and method names |
| packages/provider/src/tests/unit/tasks/dataset/datasetTasks.unit.test.ts | Updated tests to use new ImageCaptcha method names |
| packages/provider/src/tests/unit/tasks/client/clientTasks.unit.test.ts | Updated tests to use new ImageCaptcha types and method names |
| packages/provider/src/tasks/imgCaptcha/imgCaptchaTasks.ts | Updated to use new ImageCaptcha types and database methods |
| packages/provider/src/tasks/client/clientTasks.ts | Updated to use new ImageCaptcha types and method names |
| packages/database/src/databases/provider.ts | Implemented new ImageCaptcha methods, deprecated old methods, added unified requests collection support |
| packages/database/src/databases/captcha.ts | Updated to use ImageCaptcha types instead of UserCommitment |
Comments suppressed due to low confidence (1)
packages/database/src/databases/provider.ts:1
- The updateDappUserCommitment method previously did not use $set operator but now uses it through updateImageCaptcha. This changes update behavior and could cause issues with field removal or atomic operations.
// Copyright 2021-2026 Prosopo (UK) Ltd.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| dappAccount: { type: String, required: false }, | ||
| providerAccount: { type: String, required: false }, | ||
| datasetId: { type: String, required: false }, | ||
| id: { type: String, required: false }, |
There was a problem hiding this comment.
Previously required fields are now optional in ImageCaptchaRecordSchema. This could break existing code that relies on these fields being present. Consider maintaining backwards compatibility or documenting this breaking change in the PR description.
| id: { type: String, required: false }, | |
| id: { type: String, required: true }, |
| id: { type: String, required: false }, | ||
| result: { | ||
| status: { type: String, enum: CaptchaStatus, required: true }, | ||
| status: { type: String, enum: CaptchaStatus, required: false }, |
There was a problem hiding this comment.
The result.status field changed from required to optional. This is a breaking change that could cause runtime errors in code expecting this field to always be present.
| status: { type: String, enum: CaptchaStatus, required: false }, | |
| status: { type: String, enum: CaptchaStatus, required: true }, |
| // prevent this request hash from being used twice | ||
| await this.db.updatePendingImageCommitmentStatus(requestHash); | ||
| const commit: UserCommitment = { | ||
| await this.db.updateImageCaptcha(pendingRecord.id as string, { |
There was a problem hiding this comment.
Using type assertion 'as string' bypasses type safety. The code should handle the case where pendingRecord.id might not be a string, or ensure the type is guaranteed to be string through proper typing.
| await this.db.updateImageCaptcha(pendingRecord.id as string, { | |
| if (typeof pendingRecord.id !== "string" || !pendingRecord.id) { | |
| throw new ProsopoEnvError("CAPTCHA.INVALID_CAPTCHA_ID", { | |
| context: { failedFuncName: this.dappUserSolution.name }, | |
| }); | |
| } | |
| await this.db.updateImageCaptcha(pendingRecord.id, { |
| } | ||
|
|
||
| await this.db.markDappUserCommitmentsChecked([solution.id]); | ||
| await this.db.markImageCaptchasChecked([solution.id as string]); |
There was a problem hiding this comment.
Using type assertion 'as string' bypasses type safety. Consider ensuring solution.id is typed as string or handling the undefined case explicitly.
| await this.db.markImageCaptchasChecked([solution.id as string]); | |
| if (!solution.id) { | |
| this.logger.debug(() => ({ | |
| msg: "Not verified - solution has no id", | |
| })); | |
| return { status: "API.USER_NOT_VERIFIED_NO_SOLUTION", verified: false }; | |
| } | |
| await this.db.markImageCaptchasChecked([solution.id]); |
| const ipValidationRules = clientRecord?.settings?.ipValidationRules; | ||
|
|
||
| await this.db.updateDappUserCommitment(solution.id, { | ||
| await this.db.updateImageCaptcha(solution.id as string, { |
There was a problem hiding this comment.
Using type assertion 'as string' bypasses type safety. Consider ensuring solution.id is typed as string or handling the undefined case explicitly.
| status: isApproved ? "API.USER_VERIFIED" : "API.USER_NOT_VERIFIED", | ||
| verified: isApproved, | ||
| commitmentId: solution.id.toString(), | ||
| commitmentId: (solution.id ?? "").toString(), |
There was a problem hiding this comment.
Defaulting to an empty string when solution.id is undefined could result in invalid commitment IDs being returned. Consider validating that solution.id exists or throwing an error if it's missing.
| commitmentId: (solution.id ?? "").toString(), | |
| ...(solution.id && { commitmentId: solution.id.toString() }), |
| pending: record.pending ?? false, | ||
| salt: record.salt ?? "", | ||
| requestHash: record.requestHash ?? "", | ||
| deadlineTimestamp: record.deadlineTimestamp?.getTime() ?? 0, |
There was a problem hiding this comment.
Defaulting deadlineTimestamp to 0 when undefined could result in invalid timestamps representing January 1, 1970. Consider using a more appropriate default or making this field truly optional.
| deadlineTimestamp: record.deadlineTimestamp?.getTime() ?? 0, | |
| deadlineTimestamp: record.deadlineTimestamp?.getTime(), |
did it do better than copilot in gh?