Skip to content

Comments

feat(wikibase-schema-editor): implement schema selection workflow#116

Merged
DaxServer merged 1 commit intomainfrom
wikibase-editor-task31
Aug 6, 2025
Merged

feat(wikibase-schema-editor): implement schema selection workflow#116
DaxServer merged 1 commit intomainfrom
wikibase-editor-task31

Conversation

@DaxServer
Copy link
Owner

Addresses Task 31 of #66

@coderabbitai
Copy link

coderabbitai bot commented Aug 6, 2025

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Introduced a schema selection workflow, enabling users to choose or create schemas before editing.
    • Added a two-step UI flow for schema selection and editing, with navigation controls and improved loading states.
    • Enhanced validation feedback with detailed status and improved completeness information for schemas.
  • Bug Fixes

    • Improved error handling and robustness in date formatting and schema completeness checks.
  • Tests

    • Added comprehensive tests for schema selection, schema completeness validation, and backend-to-frontend schema data transformation.
  • Chores

    • Updated configuration and type declarations to support new schema selection features.
    • Added a new frontend error code for schema selection failures.

Walkthrough

This change introduces a schema selection workflow to the Wikibase schema editor feature. It adds a new useSchemaSelection composable, updates the editor and selector components to support view transitions, refactors API and validation logic for consistency, enhances error handling, and adds comprehensive tests for the new and updated workflows.

Changes

Cohort / File(s) Change Summary
Task Completion
.kiro/specs/wikibase-schema-editor/tasks.md
Marked the "Implement schema selection workflow" task as completed.
ESLint & Auto-Import Declarations
frontend/.eslintrc-auto-import.json, frontend/auto-imports.d.ts
Added useSchemaSelection to ESLint auto-imports and TypeScript global declarations.
Schema Selector Component
frontend/src/features/wikibase-schema/components/SchemaSelector.vue
Enhanced date formatting robustness, replaced local completeness info function with composable import, updated template bindings for safety, and improved icon syntax.
Wikibase Schema Editor Component
frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue
Integrated schema selection workflow, added view transitions, conditional validation, UI controls, and refactored schema loading logic.
Schema API Composables
frontend/src/features/wikibase-schema/composables/useSchemaApi.ts
Centralized backend-to-frontend schema transformation, added loading state management helpers, and refactored all API functions for consistency.
Schema Completeness Validation
frontend/src/features/wikibase-schema/composables/useSchemaCompletenessValidation.ts
Added getSchemaCompletionInfo method to summarize schema completeness and term counts.
Schema Selection Composable
frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
Introduced new composable managing schema selection, creation, and view transitions.
Validation UI Composable
frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts
Removed isComplete property from returned object and destructuring.
Frontend Error Codes
frontend/src/shared/types/client-errors.ts
Added 'SCHEMA_SELECTION_FAILED' to the error code union type.
Tests: Schema API
frontend/src/features/wikibase-schema/composables/__tests__/useSchemaApi.test.ts
Updated tests to use backend-format mock data and verify transformation to frontend schema objects.
Tests: Completeness Validation
frontend/src/features/wikibase-schema/composables/__tests__/useSchemaCompletenessValidation.test.ts
Added tests for getSchemaCompletionInfo covering various schema states (populated, null, empty).
Tests: Schema Selection
frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
Added new test suite for useSchemaSelection, covering state initialization and workflow transitions.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SchemaSelector
    participant useSchemaSelection
    participant WikibaseSchemaEditor
    participant useSchemaApi
    participant SchemaStore

    User->>SchemaSelector: Selects schema or clicks "Create New"
    SchemaSelector->>useSchemaSelection: selectSchema(schemaId) or createNewSchema()
    alt Selecting existing schema
        useSchemaSelection->>useSchemaApi: loadSchema(projectId, schemaId)
        useSchemaApi->>SchemaStore: loadSchemaIntoStore(schema)
        useSchemaSelection->>WikibaseSchemaEditor: showMainEditor = true
    else Creating new schema
        useSchemaSelection->>SchemaStore: initializeEmptySchema()
        useSchemaSelection->>WikibaseSchemaEditor: showMainEditor = true
    end
    User->>WikibaseSchemaEditor: Edits schema, uses toolbar actions
    User->>WikibaseSchemaEditor: Clicks "Back"
    WikibaseSchemaEditor->>useSchemaSelection: backToSelector()
    useSchemaSelection->>SchemaStore: reset()
    useSchemaSelection->>SchemaSelector: showSchemaSelector = true
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

  • DaxServer/dataforge#111: Implements the schema selection workflow and integrates useSchemaSelection into the editor, directly addressing the same feature.
  • DaxServer/dataforge#82: Introduces the initial editor container for WikibaseSchemaEditor.vue, which this PR extends with schema selection.
  • DaxServer/dataforge#114: Adds and registers the standalone SchemaSelector.vue component, which is now integrated into the schema selection workflow.

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch wikibase-editor-task31

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🔭 Outside diff range comments (1)
frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue (1)

18-18: Remove unused import

The loadSchema import is not used in this component.

 // Composables
-const { loadSchema } = useSchemaApi()
 const { showError, showSuccess } = useErrorHandling()
🧹 Nitpick comments (4)
frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts (1)

182-192: Consider using the new completion info method for consistency.

The getValidationSummary method manually sets isComplete: result.isComplete, but could potentially leverage the new getSchemaCompletionInfo method from the completeness validation composable for consistency.

frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts (1)

1-87: Good test foundation, but consider expanding coverage.

The test structure follows best practices with Bun testing and proper Pinia setup. However, the test coverage could be more comprehensive.

Consider adding tests for:

  1. The selectSchema method with both success and error scenarios
  2. Loading states during schema selection
  3. Error handling when schema loading fails
  4. Edge cases like selecting the same schema twice

Example test for selectSchema:

it('should handle successful schema selection', async () => {
  const mockSchema: WikibaseSchemaMapping = {
    id: Bun.randomUUIDv7() as UUID,
    projectId: TEST_PROJECT_ID,
    name: 'Test Schema',
    wikibase: 'https://test.wikibase.org',
    item: { terms: { labels: {}, descriptions: {}, aliases: {} }, statements: [] },
    createdAt: '2024-01-01T00:00:00Z',
    updatedAt: '2024-01-01T00:00:00Z',
  }

  mockLoadSchema.mockResolvedValueOnce(undefined)

  const { selectSchema, selectedSchema, showSchemaSelector, showMainEditor, isLoadingSchema } = useSchemaSelection()

  await selectSchema(mockSchema)

  expect(selectedSchema.value).toBe(mockSchema)
  expect(showSchemaSelector.value).toBe(false)
  expect(showMainEditor.value).toBe(true)
  expect(isLoadingSchema.value).toBe(false)
})
frontend/src/features/wikibase-schema/composables/useSchemaApi.ts (1)

48-55: Consider consolidating updateStoreFromSchema with loadSchemaIntoStore

Both updateStoreFromSchema and loadSchemaIntoStore update store properties. This creates maintenance overhead and potential for inconsistency.

Consider having a single method with an option to update only metadata:

-const updateStoreFromSchema = (schema: WikibaseSchemaMapping) => {
-  schemaStore.schemaId = schema.id
-  schemaStore.projectId = schema.projectId
-  schemaStore.schemaName = schema.name
-  schemaStore.wikibase = schema.wikibase
-  schemaStore.createdAt = schema.createdAt
-  schemaStore.updatedAt = schema.updatedAt
-}

-const loadSchemaIntoStore = (schema: WikibaseSchemaMapping) => {
+const loadSchemaIntoStore = (schema: WikibaseSchemaMapping, metadataOnly = false) => {
   schemaStore.schemaId = schema.id
   schemaStore.projectId = schema.projectId
   schemaStore.schemaName = schema.name
   schemaStore.wikibase = schema.wikibase
+  schemaStore.createdAt = schema.createdAt
+  schemaStore.updatedAt = schema.updatedAt
+  
+  if (!metadataOnly) {
     schemaStore.labels = schema.item?.terms?.labels || {}
     schemaStore.descriptions = schema.item?.terms?.descriptions || {}
     schemaStore.aliases = schema.item?.terms?.aliases || {}
     schemaStore.statements = schema.item?.statements || []
-    schemaStore.createdAt = schema.createdAt
-     schemaStore.updatedAt = schema.updatedAt
     schemaStore.isDirty = false
     schemaStore.lastSaved = new Date(schema.updatedAt)
+  }
 }

Then update the calls to use loadSchemaIntoStore(createdSchema, true) where only metadata is needed.

frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue (1)

23-25: Group import statements together

The import statement for createFrontendError should be grouped with other imports at the top of the script section.

Move the import to the top with other type imports:

 <script setup lang="ts">
+import { createFrontendError } from '@frontend/shared/types/client-errors'
+
 interface WikibaseSchemaEditorEmits {
   'add-item': []
   preview: []
   save: []
   help: []
 }

 const emit = defineEmits<WikibaseSchemaEditorEmits>()

 // Store instances
 const schemaStore = useSchemaStore()
 const dragDropStore = useDragDropStore()
 const validationStore = useValidationStore()
 const projectStore = useProjectStore()

 // Composables
 const { showError, showSuccess } = useErrorHandling()
 const { convertProjectColumnsToColumnInfo } = useColumnConversion()
 const { setAvailableColumns, initializeStatement, resetStatement } = useStatementEditor()

-// Import createFrontendError for error handling
-import { createFrontendError } from '@frontend/shared/types/client-errors'
-
 // Schema selection workflow composable
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0297058 and ece6a68.

📒 Files selected for processing (13)
  • .kiro/specs/wikibase-schema-editor/tasks.md (1 hunks)
  • frontend/.eslintrc-auto-import.json (1 hunks)
  • frontend/auto-imports.d.ts (2 hunks)
  • frontend/src/features/wikibase-schema/components/SchemaSelector.vue (7 hunks)
  • frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue (4 hunks)
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaApi.test.ts (3 hunks)
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaCompletenessValidation.test.ts (1 hunks)
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts (1 hunks)
  • frontend/src/features/wikibase-schema/composables/useSchemaApi.ts (2 hunks)
  • frontend/src/features/wikibase-schema/composables/useSchemaCompletenessValidation.ts (2 hunks)
  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts (1 hunks)
  • frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts (1 hunks)
  • frontend/src/shared/types/client-errors.ts (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}: Use bun <file> instead of node <file> or ts-node <file> for running TypeScript or JavaScript files
Do not use dotenv; Bun automatically loads .env files
Use Bun.serve() for HTTP servers and WebSockets instead of express
Use bun:sqlite for SQLite instead of better-sqlite3
Use Bun.redis for Redis instead of ioredis
Use Bun.sql for Postgres instead of pg or postgres.js
Use built-in WebSocket instead of ws
Prefer Bun.file over node:fs's readFile/writeFile
Use Bun.$ (e.g., Bun.$ls``) instead of execa for running shell commands

Files:

  • frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaCompletenessValidation.test.ts
  • frontend/src/shared/types/client-errors.ts
  • frontend/auto-imports.d.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaCompletenessValidation.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaApi.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaApi.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 of webpack or esbuild for building HTML, TypeScript, or CSS files

Files:

  • frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaCompletenessValidation.test.ts
  • frontend/src/shared/types/client-errors.ts
  • frontend/auto-imports.d.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaCompletenessValidation.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaApi.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaApi.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit Inference Engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun test instead of jest for running tests

Files:

  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaCompletenessValidation.test.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaApi.test.ts
🧠 Learnings (21)
📚 Learning: applies to src/composables/**/*.ts : use composables for logic that is not global state...
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/composables/**/*.ts : Use composables for logic that is not global state

Applied to files:

  • frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue
  • frontend/auto-imports.d.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaCompletenessValidation.ts
📚 Learning: applies to src/composables/**/*.ts : do not export store state from composables...
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/composables/**/*.ts : Do not export store state from composables

Applied to files:

  • frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/auto-imports.d.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
📚 Learning: applies to src/**/*.vue : use storetorefs for state in components...
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 : Use storeToRefs for state in components

Applied to files:

  • frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/auto-imports.d.ts
📚 Learning: applies to src/**/*.{vue,ts} : use useapi composable (elysia eden) for all api calls...
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:

  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue
  • frontend/auto-imports.d.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
  • frontend/src/features/wikibase-schema/composables/useSchemaApi.ts
📚 Learning: applies to src/**/*.vue : use vue 3 with composition api and <script setup lang="ts"> in all vue com...
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 : Use Vue 3 with Composition API and <script setup lang="ts"> in all Vue components

Applied to files:

  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/auto-imports.d.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
📚 Learning: applies to src/composables/**/*.ts : place composables in the composables/ directory...
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/composables/**/*.ts : Place composables in the composables/ directory

Applied to files:

  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
📚 Learning: applies to src/**/*.vue : prefer composables over methods in vue components...
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 : Prefer composables over methods in Vue components

Applied to files:

  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue
  • frontend/auto-imports.d.ts
📚 Learning: applies to src/**/*.{vue,ts} : handle errors and loading states reactively when making api calls...
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} : Handle errors and loading states reactively when making API calls

Applied to files:

  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
📚 Learning: applies to src/**/*.vue : use reactive objects for form state and errors...
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 : Use reactive objects for form state and errors

Applied to files:

  • frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
  • frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue
📚 Learning: applies to src/**/*.vue : use auto-imports for vue, pinia, composables, and utilities...
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 : Use auto-imports for Vue, Pinia, composables, and utilities

Applied to files:

  • frontend/.eslintrc-auto-import.json
  • frontend/auto-imports.d.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
📚 Learning: applies to **/*.{tsx,jsx,js} : import .css files directly in .tsx, .jsx, or .js files and bun will h...
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-20T14:13:40.153Z
Learning: Applies to **/*.{tsx,jsx,js} : Import .css files directly in .tsx, .jsx, or .js files and Bun will handle them

Applied to files:

  • frontend/.eslintrc-auto-import.json
📚 Learning: applies to src/**/*.{vue,ts} : use readonly and shallowreactive for large or expensive data...
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 readonly and shallowReactive for large or expensive data

Applied to files:

  • frontend/auto-imports.d.ts
📚 Learning: applies to src/**/*.{vue,ts} : always use backend-inferred types for api data...
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} : Always use backend-inferred types for API data

Applied to files:

  • frontend/auto-imports.d.ts
📚 Learning: applies to src/**/*.{vue,ts} : use pinia stores for global state...
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 Pinia stores for global state

Applied to files:

  • frontend/auto-imports.d.ts
  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
📚 Learning: applies to src/**/*.{ts,vue} : type safety everywhere...
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/**/*.{ts,vue} : Type safety everywhere

Applied to files:

  • frontend/auto-imports.d.ts
📚 Learning: applies to src/**/*.vue : props and emits must use explicit typescript interfaces...
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 : Props and emits must use explicit TypeScript interfaces

Applied to files:

  • frontend/auto-imports.d.ts
📚 Learning: applies to src/**/*.vue : use primevue as the ui library in all vue components...
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 : Use PrimeVue as the UI library in all Vue components

Applied to files:

  • frontend/auto-imports.d.ts
📚 Learning: applies to src/**/*.vue : use v-memo, shallowref, markraw, and suspense for performance optimization...
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 : Use v-memo, shallowRef, markRaw, and Suspense for performance optimization

Applied to files:

  • frontend/auto-imports.d.ts
📚 Learning: applies to src/composables/**/*.ts : do not proxy or export pinia store state/actions from composabl...
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/composables/**/*.ts : Do not proxy or export Pinia store state/actions from composables

Applied to files:

  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
📚 Learning: applies to src/**/*.vue : use pinia for state management in all vue components...
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 : Use Pinia for state management in all Vue components

Applied to files:

  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
📚 Learning: applies to **/*.test.{ts,tsx,js,jsx} : use `bun test` instead of `jest` for running tests...
Learnt from: CR
PR: DaxServer/dataforge#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-20T14:13:40.153Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Use `bun test` instead of `jest` for running tests

Applied to files:

  • frontend/src/features/wikibase-schema/composables/__tests__/useSchemaSelection.test.ts
🧬 Code Graph Analysis (2)
frontend/auto-imports.d.ts (1)
frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts (1)
  • useSchemaSelection (10-92)
frontend/src/features/wikibase-schema/composables/__tests__/useSchemaApi.test.ts (1)
frontend/src/features/wikibase-schema/composables/useSchemaApi.ts (1)
  • useSchemaApi (9-169)
🪛 GitHub Actions: Typecheck code
frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue

[error] 18-18: TypeScript error TS6133: 'loadSchema' is declared but its value is never read.


[error] 28-28: TypeScript error TS6133: 'selectedSchema' is declared but its value is never read.

🔇 Additional comments (14)
frontend/src/shared/types/client-errors.ts (1)

13-13: LGTM! Clean addition of error code.

The new SCHEMA_SELECTION_FAILED error code follows the existing naming convention and is appropriately placed within the FrontendErrorCode union type for client-side failures.

frontend/src/features/wikibase-schema/composables/useSchemaCompletenessValidation.ts (1)

210-257: Well-implemented completion info method with excellent defensive programming.

The method includes proper null/undefined checks and provides sensible fallbacks. The logic for calculating completion statistics is clear and the completeness criteria (having at least one term and one statement) is reasonable.

.kiro/specs/wikibase-schema-editor/tasks.md (1)

185-185: Task completion appropriately tracked.

The completion of Task 31 aligns with the PR objectives and the schema selection workflow implementation found in the codebase.

frontend/.eslintrc-auto-import.json (1)

340-340: Auto-import configuration correctly updated.

The addition of useSchemaSelection follows the established pattern and enables seamless usage of the new composable across components, aligning with the frontend setup guidelines for auto-importing composables.

frontend/src/features/wikibase-schema/composables/useSchemaValidationUI.ts (1)

34-34: Safe to remove isComplete from useSchemaValidationUI – refactoring approved

No occurrences of isComplete were found across TS/Vue files, confirming that no consumer still relies on it.

  • All calls to useSchemaValidationUI now use the new getSchemaCompletionInfo method.
  • Removal of isComplete is safe and aligns with the refactoring.
  • Consider updating getValidationSummary (if present) to leverage getSchemaCompletionInfo for consistency.
frontend/auto-imports.d.ts (1)

276-276: LGTM! Auto-generated declarations are correct.

The auto-generated TypeScript declarations for the useSchemaSelection composable follow the correct pattern and are consistent with other composables in the file.

Also applies to: 671-671

frontend/src/features/wikibase-schema/composables/__tests__/useSchemaApi.test.ts (1)

315-372: Excellent improvement to test realism and coverage.

The tests now properly mock backend data format with snake_case keys and verify the transformation to frontend camelCase format. This is much more realistic and tests the actual data transformation logic.

The new test 'should properly map backend schema structure to frontend format' provides excellent coverage of the transformBackendSchema helper function, ensuring that:

  • snake_case keys are converted to camelCase (project_idprojectId)
  • Date fields are properly mapped (created_atcreatedAt, updated_atupdatedAt)
  • Schema content is nested under the item property

This aligns well with the backend API integration and provides confidence in the data transformation layer.

Also applies to: 402-438

frontend/src/features/wikibase-schema/composables/__tests__/useSchemaCompletenessValidation.test.ts (1)

292-403: Comprehensive test coverage for schema completion metrics.

The new test suite for getSchemaCompletionInfo provides excellent coverage of all scenarios:

  • Normal case: Verifies correct counting of labels (2), descriptions (1), aliases (1 language), statements (1), and total terms calculation (4)
  • Edge cases: Properly handles null item, null schema, and empty schema inputs
  • Robustness: Tests ensure the method gracefully handles malformed data without throwing errors

The test data setup is realistic and the assertions comprehensively verify all returned metrics (labelCount, descriptionCount, aliasCount, statementCount, totalTerms, isComplete). This ensures the completeness calculation logic is reliable for the schema selection workflow.

frontend/src/features/wikibase-schema/components/SchemaSelector.vue (4)

12-12: Good refactoring to use centralized composable.

Replacing the local getSchemaCompletionInfo function with the centralized composable from useSchemaCompletenessValidation improves code reusability and consistency across components.


23-57: Excellent error handling improvements for date formatting.

The enhanced error handling in both formatDate and formatDateTime functions significantly improves robustness by:

  • Checking for invalid/empty date strings before processing
  • Wrapping date parsing in try-catch blocks
  • Providing meaningful fallbacks for invalid dates
  • Adding helpful console warnings for debugging

This prevents potential runtime crashes when dealing with malformed date data from the backend.


168-198: Smart defensive programming with optional chaining.

The template updates use optional chaining (getSchemaCompletionInfo(schema)?.statementCount) and provide sensible fallbacks (|| 0) to prevent runtime errors when the completion info might be undefined.

This defensive approach ensures the UI remains stable even when schema data is incomplete or malformed.


140-140: Minor template syntax improvements.

The icon tag syntax has been correctly updated to use the standard <i> tag format for PrimeVue icons.

Also applies to: 151-151, 158-158, 219-219

frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue (2)

104-120: LGTM! Clean lifecycle management for validation

The implementation properly manages validation lifecycle based on view transitions, ensuring validation is only active when the main editor is shown.


357-591: Well-structured multi-view implementation

The template reorganization cleanly separates the schema selector and editor views with proper loading states and transitions. The conditional rendering logic is clear and maintainable.


// Schema selection workflow composable
const {
selectedSchema,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unused destructured variable

The selectedSchema variable is destructured but never used in the component.

 const {
-  selectedSchema,
   isLoadingSchema,
   showSchemaSelector,
   showMainEditor,
   selectSchema,
   createNewSchema,
   backToSelector,
 } = useSchemaSelection()
📝 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.

Suggested change
selectedSchema,
const {
isLoadingSchema,
showSchemaSelector,
showMainEditor,
selectSchema,
createNewSchema,
backToSelector,
} = useSchemaSelection()
🧰 Tools
🪛 GitHub Actions: Typecheck code

[error] 28-28: TypeScript error TS6133: 'selectedSchema' is declared but its value is never read.

🤖 Prompt for AI Agents
In frontend/src/features/wikibase-schema/components/WikibaseSchemaEditor.vue at
line 28, the variable selectedSchema is destructured but not used anywhere in
the component. Remove selectedSchema from the destructuring assignment to clean
up the code and avoid unused variable warnings.

Comment on lines +86 to 103
const createSchema = async (projectId: UUID, schemaData: CreateSchemaRequest) => {
return withLoadingState(async () => {
const { data, error: apiError } = await api.project({ projectId }).schemas.post({
projectId,
name: schemaData.name,
wikibase: schemaData.wikibase,
})

if (apiError) {
showError(apiError.value as ApiError)
} else if (data && typeof data === 'object' && 'data' in data) {
const rawSchema = (data as { data: Record<string, unknown> }).data
const createdSchema = transformBackendSchema(rawSchema, projectId)
updateStoreFromSchema(createdSchema)
return createdSchema
}
})
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove redundant projectId from POST body

The projectId is already part of the URL path and shouldn't be duplicated in the request body.

 const createSchema = async (projectId: UUID, schemaData: CreateSchemaRequest) => {
   return withLoadingState(async () => {
     const { data, error: apiError } = await api.project({ projectId }).schemas.post({
-      projectId,
       name: schemaData.name,
       wikibase: schemaData.wikibase,
     })
📝 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.

Suggested change
const createSchema = async (projectId: UUID, schemaData: CreateSchemaRequest) => {
return withLoadingState(async () => {
const { data, error: apiError } = await api.project({ projectId }).schemas.post({
projectId,
name: schemaData.name,
wikibase: schemaData.wikibase,
})
if (apiError) {
showError(apiError.value as ApiError)
} else if (data && typeof data === 'object' && 'data' in data) {
const rawSchema = (data as { data: Record<string, unknown> }).data
const createdSchema = transformBackendSchema(rawSchema, projectId)
updateStoreFromSchema(createdSchema)
return createdSchema
}
})
}
const createSchema = async (projectId: UUID, schemaData: CreateSchemaRequest) => {
return withLoadingState(async () => {
const { data, error: apiError } = await api.project({ projectId }).schemas.post({
name: schemaData.name,
wikibase: schemaData.wikibase,
})
if (apiError) {
showError(apiError.value as ApiError)
} else if (data && typeof data === 'object' && 'data' in data) {
const rawSchema = (data as { data: Record<string, unknown> }).data
const createdSchema = transformBackendSchema(rawSchema, projectId)
updateStoreFromSchema(createdSchema)
return createdSchema
}
})
}
🤖 Prompt for AI Agents
In frontend/src/features/wikibase-schema/composables/useSchemaApi.ts around
lines 86 to 103, the createSchema function includes projectId in the POST
request body, which is redundant since projectId is already part of the URL
path. Remove the projectId property from the object passed to the schemas.post
method, keeping only the necessary schemaData fields like name and wikibase.

/**
* Get schema completion information for display purposes
*/
const getSchemaCompletionInfo = (schema: WikibaseSchemaMapping) => {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add missing type import.

The WikibaseSchemaMapping type is used but not imported. This will cause TypeScript compilation errors.

Add the import at the top of the file:

+import type { WikibaseSchemaMapping } from '@frontend/shared/types/wikibase-schema'
📝 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.

Suggested change
const getSchemaCompletionInfo = (schema: WikibaseSchemaMapping) => {
import type { WikibaseSchemaMapping } from '@frontend/shared/types/wikibase-schema'
const getSchemaCompletionInfo = (schema: WikibaseSchemaMapping) => {
🤖 Prompt for AI Agents
In
frontend/src/features/wikibase-schema/composables/useSchemaCompletenessValidation.ts
at line 213, the type WikibaseSchemaMapping is used but not imported, causing
TypeScript errors. Fix this by adding an import statement for
WikibaseSchemaMapping at the top of the file from its appropriate module or
path.

Comment on lines +50 to +65
const createNewSchema = () => {
// Initialize empty schema in store
schemaStore.projectId = projectId.value
schemaStore.schemaName = 'Untitled Schema'
schemaStore.wikibase = 'https://www.wikidata.org'
schemaStore.schemaId = null
schemaStore.itemId = null

// Clear selected schema reference
selectedSchema.value = null

// Transition to main editor
currentView.value = 'editor'

// Don't mark as dirty - only when user makes actual changes
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use a store method instead of direct property mutations

Directly mutating multiple store properties violates encapsulation. Consider using a dedicated store method for initializing a new schema.

Add a method to the schema store and use it here:

 const createNewSchema = () => {
-  // Initialize empty schema in store
-  schemaStore.projectId = projectId.value
-  schemaStore.schemaName = 'Untitled Schema'
-  schemaStore.wikibase = 'https://www.wikidata.org'
-  schemaStore.schemaId = null
-  schemaStore.itemId = null
+  // Initialize empty schema in store
+  schemaStore.initializeNewSchema(projectId.value)

   // Clear selected schema reference
   selectedSchema.value = null

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
around lines 50 to 65, the code directly mutates multiple properties of the
schema store, which breaks encapsulation. To fix this, add a dedicated method in
the schema store that initializes a new schema with the required default values,
then replace the direct property assignments in createNewSchema with a call to
this new store method.

🛠️ Refactor suggestion

Consider extracting the hardcoded Wikibase URL to configuration

The Wikibase URL is hardcoded to 'https://www.wikidata.org'. This should be configurable based on the environment or project settings.

Consider using a configuration value or deriving it from project settings:

 const createNewSchema = () => {
   // Initialize empty schema in store
   schemaStore.projectId = projectId.value
   schemaStore.schemaName = 'Untitled Schema'
-  schemaStore.wikibase = 'https://www.wikidata.org'
+  schemaStore.wikibase = projectStore.defaultWikibaseUrl || 'https://www.wikidata.org'
   schemaStore.schemaId = null
   schemaStore.itemId = null

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In frontend/src/features/wikibase-schema/composables/useSchemaSelection.ts
around lines 50 to 65, the Wikibase URL is hardcoded as
'https://www.wikidata.org'. To fix this, extract this URL into a configuration
file or environment variable and replace the hardcoded string with a reference
to that configuration. This will allow the URL to be configurable based on
environment or project settings.

@DaxServer DaxServer merged commit 2a85bdb into main Aug 6, 2025
5 of 6 checks passed
@DaxServer DaxServer deleted the wikibase-editor-task31 branch August 6, 2025 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant