feat(wikibase-integration): set up project dependencies and core types#138
feat(wikibase-integration): set up project dependencies and core types#138
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds Wikibase REST API typings, a structured error system with retry/backoff utilities, corresponding tests, and a new dependency. Multiple spec markdown files receive formatting-only edits. A frontend DropZone component is reformatted without behavior change. Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant ErrorHandler
participant Operation
Caller->>ErrorHandler: withRetry(operation, context)
loop attempts until success or non-retryable/max
ErrorHandler->>Operation: execute()
alt success
Operation-->>ErrorHandler: result
ErrorHandler-->>Caller: result
else throws error
Operation-->>ErrorHandler: error
ErrorHandler->>ErrorHandler: handleApiError(error, context) -> WikibaseError
alt retryable and attempts left
ErrorHandler->>ErrorHandler: wait(backoff)
else non-retryable or exhausted
ErrorHandler-->>Caller: throw WikibaseError
end
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (18)
frontend/src/features/wikibase-schema/components/DropZone.vue (1)
71-73: Ternary reformat is fine; minor readability nitFunctionally equivalent. Consider computing the validation once to avoid calling it twice and to improve readability.
Apply:
- event.dataTransfer.dropEffect = validateColumnForTarget(dragDropStore.draggedColumn) - ? 'copy' - : 'none' + const isValid = validateColumnForTarget(dragDropStore.draggedColumn) + event.dataTransfer.dropEffect = isValid ? 'copy' : 'none'.kiro/specs/wikibase-schema-editor/design.md (2)
306-308: Consider renaming “statements1” for clarity“statements1” is ambiguous in docs. If the dual storage stays, prefer a more descriptive name like “statementsById” to signal map-based structure.
Suggested rename in the doc snippet:
- statements1: Record<UUID, StatementSchema> // Object format for editing + statementsById: Record<UUID, StatementSchema> // Object format for editing
649-658: Align API usage with project convention (useApi/Eden)Per team learnings, route all API calls through the Eden-based useApi composable. Ensure useSchemaApi is implemented on top of that, not bypassing it.
.kiro/specs/wikibase-rest-api-integration/tasks.md (1)
3-7: Traceability suggestion: link specs to implementationNow that Task 1 is checked, consider adding brief references to the modules added (types, errors, handler, tests) for easy traceability from this checklist to code.
.kiro/specs/wikibase-rest-api-integration/design.md (2)
160-179: Align frontend error typing with new backend error modelConsider typing
errorasRef<WikibaseError | null>(from backend types) instead ofRef<string | null>so consumers can branch on error.code, statusCode, retryable, etc. This keeps the frontend and backend aligned on the structured error model introduced in this PR.
83-92: Clarify cache invalidation semantics
invalidate(pattern: string)needs a documented pattern format (glob, prefix, regex?) and scoping (per-instance vs global). Ambiguity here can lead to accidental cache poisoning or missed invalidations.backend/src/types/wikibase-errors.ts (4)
36-47: Add standard Error.cause and name to improve debuggabilityIncluding
causein the interface lets us chain original errors interoperably with modern runtimes, and settingnameimproves stack readability.Apply this diff:
export interface WikibaseError extends Error { code: WikibaseErrorCode instanceId?: string propertyId?: string itemId?: string retryable: boolean fallbackData?: any originalError?: Error + // Standardized error chaining support + cause?: unknown statusCode?: number details?: Record<string, any> }
55-63: Initialize error.name and propagate cause for better error chainingSet a descriptive name and wire
originalErrorto the standardcausefield to preserve stack context across layers.Apply this diff:
const error = new Error(message) as WikibaseError + error.name = 'WikibaseError' error.code = code error.retryable = isRetryableError(code) // Copy additional properties Object.assign(error, options) + + // Preserve original error chain using standard cause + if (options.originalError && error.cause === undefined) { + error.cause = options.originalError + } return error
100-109: Expose statusCode in ErrorResponse for clientsIncluding
statusCodeallows clients to adjust UX without needing to parsedetails.Apply this diff:
export interface ErrorResponse { error: { code: WikibaseErrorCode message: string details?: Record<string, any> instanceId?: string + statusCode?: number timestamp: string } fallbackData?: any }
119-124: Document time units in RetryConfigClarify that delays are milliseconds to avoid misconfiguration.
I recommend a short JSDoc like “baseDelay/maxDelay are in milliseconds”.
backend/src/types/wikibase-api.ts (3)
79-82: Refine StatementValue typing to a discriminated union (when ready)
content: anyis pragmatic to start, but long-term consider a discriminated union keyed bytype(e.g., 'string' | 'time' | 'wikibase-item' | 'quantity', etc.) to gain exhaustiveness checks and better DX. If you plan to mirror@wmde/wikibase-rest-apitypes, aligning here will reduce mapping code.
106-112: Confirm single vs. multi data type filtering
SearchOptionsusesdataType?: string, while the UI props in the design doc showdataTypeFilter?: string[]. If multi-type filtering is desired at the API boundary, considerdataTypes?: string[]here to avoid lossy conversions.
156-161: Clarify CacheEntry.ttl unitsPlease document whether
ttlis milliseconds or seconds. Mismatched assumptions here are a frequent source of cache bugs.backend/tests/wikibase-error-handler.test.ts (1)
127-138: Consider adding a retry timing/assertion testAdd a test that forces one retryable failure then success to assert retry attempts and that non-zero backoff is applied. You can inject a small custom RetryConfig to keep tests fast.
backend/src/utils/wikibase-error-handler.ts (4)
33-43: Broaden network error detection (DNS resets, transient host issues)Include common transient network codes like ECONNRESET/EAI_AGAIN/EHOSTUNREACH to reduce UNKNOWN_ERROR leakage.
Apply this diff:
- if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') { + if ( + error.code === 'ECONNREFUSED' || + error.code === 'ENOTFOUND' || + error.code === 'ECONNRESET' || + error.code === 'EAI_AGAIN' || + error.code === 'EHOSTUNREACH' + ) { return createWikibaseError( WikibaseErrorCode.NETWORK_ERROR, `Network connection failed: ${error.message}`, { ...context, originalError: error, retryable: true, }, ) }
186-194: Unify context naming: operation vs operationName
handleApiErrorusesoperation, whilewithRetryusesoperationName. Pick one to avoid confusion.Apply this diff:
async withRetry<T>( operation: () => Promise<T>, context: { instanceId?: string propertyId?: string itemId?: string - operationName?: string + operation?: string } = {}, ): Promise<T> {
210-217: Add jitter to backoff to avoid synchronized retriesJitter reduces thundering herd effects when many clients retry simultaneously.
Apply this diff:
- const delay = Math.min( - this.retryConfig.baseDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt - 1), - this.retryConfig.maxDelay, - ) + const base = Math.min( + this.retryConfig.baseDelay * Math.pow(this.retryConfig.backoffMultiplier, attempt - 1), + this.retryConfig.maxDelay, + ) + // Full jitter + const delay = Math.floor(Math.random() * base)
226-237: Include statusCode in serialized ErrorResponseThis matches the ErrorResponse type update and saves clients from scraping details.
Apply this diff:
toErrorResponse = (error: WikibaseError): ErrorResponse => { return { error: { code: error.code, message: error.message, details: error.details, instanceId: error.instanceId, + statusCode: error.statusCode, timestamp: new Date().toISOString(), }, fallbackData: error.fallbackData, } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
.kiro/specs/wikibase-rest-api-integration/design.md(6 hunks).kiro/specs/wikibase-rest-api-integration/tasks.md(1 hunks).kiro/specs/wikibase-schema-editor/design.md(6 hunks).kiro/specs/wikibase-schema-editor/requirements.md(1 hunks)backend/package.json(1 hunks)backend/src/types/wikibase-api.ts(1 hunks)backend/src/types/wikibase-errors.ts(1 hunks)backend/src/utils/wikibase-error-handler.ts(1 hunks)backend/tests/wikibase-error-handler.test.ts(1 hunks)frontend/src/features/wikibase-schema/components/DropZone.vue(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
**/*.{ts,tsx,js,jsx}: Usebun <file>instead ofnode <file>orts-node <file>for running TypeScript or JavaScript files
Do not use dotenv; Bun automatically loads .env files
UseBun.serve()for HTTP servers and WebSockets instead ofexpress
Usebun:sqlitefor SQLite instead ofbetter-sqlite3
UseBun.redisfor Redis instead ofioredis
UseBun.sqlfor Postgres instead ofpgorpostgres.js
Use built-inWebSocketinstead ofws
PreferBun.fileovernode:fs's readFile/writeFile
UseBun.$(e.g.,Bun.$ls``) instead of execa for running shell commands
Files:
backend/tests/wikibase-error-handler.test.tsbackend/src/types/wikibase-api.tsbackend/src/types/wikibase-errors.tsbackend/src/utils/wikibase-error-handler.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Use
bun testinstead ofjestfor running tests
Files:
backend/tests/wikibase-error-handler.test.ts
**/*.{html,ts,tsx,css}
📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Use
bun build <file.html|file.ts|file.css>instead ofwebpackoresbuildfor building HTML, TypeScript, or CSS files
Files:
backend/tests/wikibase-error-handler.test.tsbackend/src/types/wikibase-api.tsbackend/src/types/wikibase-errors.tsbackend/src/utils/wikibase-error-handler.ts
🧠 Learnings (1)
📚 Learning: 2025-07-20T14:13:24.706Z
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/frontend-setup.rule.md:0-0
Timestamp: 2025-07-20T14:13:24.706Z
Learning: Applies to src/**/*.{vue,ts} : Use useApi composable (Elysia Eden) for all API calls
Applied to files:
.kiro/specs/wikibase-schema-editor/design.md
🧬 Code Graph Analysis (2)
backend/tests/wikibase-error-handler.test.ts (2)
backend/src/types/wikibase-errors.ts (4)
createWikibaseError(50-63)isRetryableError(66-76)isAuthenticationError(78-86)isValidationError(88-97)backend/src/utils/wikibase-error-handler.ts (4)
WikibaseErrorHandler(13-238)handleWikibaseError(244-244)withRetry(186-221)withRetry(245-245)
backend/src/utils/wikibase-error-handler.ts (1)
backend/src/types/wikibase-errors.ts (5)
RetryConfig(112-117)DEFAULT_RETRY_CONFIG(119-124)WikibaseError(37-47)createWikibaseError(50-63)ErrorResponse(100-109)
🔇 Additional comments (10)
.kiro/specs/wikibase-rest-api-integration/tasks.md (1)
3-3: Marking Task 1 as done looks correctMatches the added dependency and new core types/utilities in backend. No further changes needed here.
backend/package.json (1)
22-22: Dependency metadata verified
- @wmde/[email protected] is the latest published version.
- License is BSD-3-Clause.
- No
enginesfield—no Node version restrictions.- Package.json defines
"main": "dist/index.js"with no"module"or"exports"entry and no"type": "module", i.e. it ships as CommonJS only.Please confirm that this CommonJS-only package imports and runs correctly under Bun’s ESM-first environment or work with the maintainers to publish an ESM-compatible build.
.kiro/specs/wikibase-schema-editor/requirements.md (1)
8-8: Blank line after “including:” improves readabilityThe spacing tweak before the bullet list is good.
.kiro/specs/wikibase-schema-editor/design.md (4)
8-8: Formatting-only change acknowledgedNo semantic impact. Looks good.
257-261: Type union formatting looks goodNo structural change to ValueMapping; formatting is clearer.
304-304: Whitespace-only changeNo action needed.
613-619: Drag-start sequence is soundSetting DataTransfer then updating drag state and triggering validation is a solid pattern.
.kiro/specs/wikibase-rest-api-integration/design.md (1)
349-355: LGTM on test snippet changesTrailing comma in the mock object is fine and consistent with standard formatting; no behavior impact.
backend/tests/wikibase-error-handler.test.ts (2)
15-31: LGTM: WikibaseError factory and classification coverageSolid coverage for construction and helper classification. No issues.
71-86: Nice context-aware 404 mapping testVerifies property-aware INVALID_PROPERTY mapping and non-retryability. Good.
| ## Introduction | ||
|
|
||
| The Wikibase Schema Editor is a comprehensive visual interface that allows users to create and manage mappings between their tabular data and Wikibase item structures. This feature enables users to define how their data columns should be transformed into structured Wikibase format, similar to OpenRefine's Wikidata schema functionality. | ||
| The Wikibase Schema Editor is a comprehensive visual interface that allows users to create and manage mappings between their tabular data and Wikibase item structures. This feature enables users to define how their data columns should be transformed into structured Wikibase format, similar to OpenRefine's Wikidata schema functionality. |
There was a problem hiding this comment.
Duplicate introductory sentence — remove repetition
The Introduction contains a duplicated opening sentence. Keep a single instance to avoid redundancy.
Apply:
-The Wikibase Schema Editor is a comprehensive visual interface that allows users to create and manage mappings between their tabular data and Wikibase item structures. This feature enables users to define how their data columns should be transformed into structured Wikibase format, similar to OpenRefine's Wikidata schema functionality.
+The Wikibase Schema Editor is a comprehensive visual interface that allows users to create and manage mappings between their tabular data and Wikibase item structures. This feature enables users to define how their data columns should be transformed into structured Wikibase format, similar to OpenRefine's Wikidata schema functionality.Note: Remove this line if it is the second of two identical sentences in the Introduction section.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
.kiro/specs/wikibase-schema-editor/requirements.md around line 5 contains a
duplicated introductory sentence in the Introduction; remove the second
occurrence of the identical sentence so only one instance remains (delete the
repeated line at or immediately after line 5), preserving surrounding
punctuation and spacing.
| if (error.response?.status) { | ||
| const statusCode = error.response.status | ||
|
|
||
| switch (statusCode) { | ||
| case 401: |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Handle broader HTTP status shapes (fetch vs axios, generic errors)
Not all errors expose response.status. Support status and statusCode fallbacks.
Apply this diff:
- if (error.response?.status) {
- const statusCode = error.response.status
+ const statusCode = error.response?.status ?? error.status ?? error.statusCode
+ if (typeof statusCode === 'number') {📝 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.
| if (error.response?.status) { | |
| const statusCode = error.response.status | |
| switch (statusCode) { | |
| case 401: | |
| const statusCode = error.response?.status ?? error.status ?? error.statusCode | |
| if (typeof statusCode === 'number') { | |
| switch (statusCode) { | |
| case 401: | |
| // ... |
🤖 Prompt for AI Agents
In backend/src/utils/wikibase-error-handler.ts around lines 55 to 59, the code
only reads error.response?.status which misses other error shapes (e.g., fetch
Errors or generic errors with status or statusCode). Replace the status lookup
with a fallback chain like: const statusCode = error.response?.status ??
error.status ?? error.statusCode ?? null; then use that statusCode in the switch
and ensure you have a default branch for when it's null/undefined so the handler
still falls through to the generic error case.
| describe('Error Handler Utilities', () => { | ||
| test('handleWikibaseError should work as standalone function', () => { | ||
| const error = new Error('Test error') | ||
| const wikibaseError = handleWikibaseError(error, { instanceId: 'test' }) | ||
|
|
||
| expect(wikibaseError.code).toBe(WikibaseErrorCode.UNKNOWN_ERROR) | ||
| expect(wikibaseError.instanceId).toBe('test') | ||
| }) | ||
|
|
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify path alias resolution in Bun test env
The imports use @backend/... aliases. Ensure tsconfig paths are configured and Bun resolves them during bun test.
Run this quick check:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "TSConfig files:"
fd -a 'tsconfig*.json'
echo -e "\nPaths mappings:"
rg -n -C2 '"paths"\s*:\s*{' tsconfig*.json
echo -e "\nLooking for @backend/* alias:"
rg -n -C2 '"@backend/\*"' tsconfig*.jsonLength of output: 358
I’ll dig into the actual tsconfig and import usage to verify whether the @backend/* alias is set up and will work under Bun.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "→ baseUrl in backend/tsconfig.json"
rg -n '"baseUrl"' -C1 backend/tsconfig.json || echo " [NOT FOUND]"
echo -e "\n→ paths block in backend/tsconfig.json"
rg -n '"paths"' -C2 backend/tsconfig.json || echo " [NOT FOUND]"
echo -e "\n→ @backend alias entry in paths"
rg -n '"@backend/' -C2 backend/tsconfig.json || echo " [NOT FOUND]"
echo -e "\n→ Imports in the test file using @backend"
rg -n '@backend/' -C2 backend/tests/wikibase-error-handler.test.ts || echo " [NOT FOUND]"
echo -e "\n→ Presence of Bun config or import map at repo root"
fd -a bunfig.toml import_map*.json || echo " [NONE FOUND]"Length of output: 1255
Configure @backend path alias for Bun tests
The test at backend/tests/wikibase-error-handler.test.ts imports modules via @backend/..., but backend/tsconfig.json only sets baseUrl and has no paths mapping—and there’s no import_map.json or bunfig.toml at the repo root. Bun won’t resolve these aliases by default, so bun test will fail.
Please add a paths mapping and Bun import map:
• In backend/tsconfig.json under compilerOptions:
"baseUrl": ".",
+ "paths": {
+ "@backend/*": ["src/*"]
+ }• At the repo root, create an import_map.json (or add to bunfig.toml):
{
"imports": {
"@backend/": "./backend/src/"
}
}This ensures both TypeScript and Bun resolve @backend/* during tests.
🤖 Prompt for AI Agents
In backend/tests/wikibase-error-handler.test.ts around lines 118 to 126 the test
imports modules via the @backend/* alias but backend/tsconfig.json only defines
baseUrl and there is no paths mapping nor a Bun import map, so Bun test
resolution will fail; update backend/tsconfig.json to add a "paths" mapping for
"@backend/*" => ["src/*"] under compilerOptions, and add an import_map.json at
the repository root (or add equivalent entries to bunfig.toml) that maps
"@backend/" to "./backend/src/" so both TypeScript and Bun can resolve
@backend/* during tests.
Addresses Task 1 of #137