Thank you for your interest in contributing to WBProp. This document covers development guidelines, coding conventions, and testing practices.
- Node.js 20.19+ or 22.12+
- npm 9+
- Git
git clone https://github.com/johnsamuelwrites/wbprop.git
cd wbprop
npm install
npm run devThe development server starts at http://localhost:3000 with hot module replacement.
- Strict mode is enabled (
strict: trueintsconfig.json) - No unused locals or parameters (
noUnusedLocals,noUnusedParameters) - Use explicit types for function parameters and return values in service layers
- Use type inference in Vue component
<script setup>blocks where types are clear - Prefix unused callback parameters with
_(e.g.,_event)
- Use
<script setup lang="ts">for all components - Use the Composition API (no Options API)
- Props are defined with
defineProps<T>()using TypeScript interfaces - Emits are defined with
defineEmits<T>() - Keep templates readable -- extract complex logic into computed properties or functions
src/
components/ # Reusable UI components
composables/ # Vue composables (use* hooks)
config/ # Static configuration
router/ # Route definitions
services/ # Business logic and API communication
stores/ # Pinia state management
types/ # TypeScript interfaces and types
views/ # Page-level components (one per route)
Naming conventions:
- Components:
PascalCase.vue(e.g.,ChartCard.vue) - Composables:
camelCase.tswithuseprefix (e.g.,useSparqlQuery.ts) - Services:
kebab-case.ts(e.g.,query-builder.ts) - Types:
kebab-case.ts(e.g.,wikibase-config.ts) - Tests:
*.spec.tsmatching the source file name
- All SPARQL queries are generated by
QueryBuilder-- never write raw queries in views or components - Queries must be parameterized for multi-instance support
- Use
this.getPrefixes()for prefix declarations - Use
this.getLabelService()for optional label service clauses - Escape user input (search terms) before embedding in queries
- Use Vuetify components and utility classes wherever possible
- Scoped styles with
<style scoped>for component-specific CSS - Avoid inline styles unless dynamic (e.g., computed heights)
- The app supports both light and dark themes -- test both
- Create a component in
src/components/charts/ - Accept
data: ChartDataItem[]as a prop - Use ECharts (via
vue-echarts) or D3.js for rendering - Register the component in the relevant view (Dashboard or Statistics)
- Wrap it in a
<ChartCard>for consistent loading/error/export behavior
- Add the query method to
QueryBuilderinsrc/services/sparql/query-builder.ts - Create a transform function in
src/composables/useSparqlQuery.ts - Create a specialized hook (e.g.,
useMyNewStats()) wrappinguseSparqlQuery - Set the
enabledcallback if the query is instance-specific - Add unit tests in
tests/unit/query-builder.spec.ts
- Create the component in
src/views/ - Add a route in
src/router/index.tswith lazy loading:{ path: '/my-view', name: 'my-view', component: () => import('@/views/MyView.vue'), meta: { title: 'My View' }, }
- Add a navigation item in
App.vueif it should appear in the sidebar
See configuration.md for the full process.
Unit tests use Vitest and are located in tests/unit/.
# Run all tests
npm test
# Run tests in watch mode
npx vitest
# Run with UI
npm run test:uiWhat to test:
QueryBuilder-- verify generated SPARQL for each instance typeQueryCache-- test TTL, eviction, invalidation, persistence- Transform functions -- verify binding-to-data mappings
- Composable logic -- test data flow (may require mocking Pinia stores)
Test conventions:
- Use
describe/itblocks with clear descriptions - Group tests by module or class
- Use
vi.useFakeTimers()for time-dependent tests (cache TTL) - Avoid testing Vuetify rendering details -- focus on logic
E2E tests use Playwright:
npm run test:e2eTo simulate what runs in CI locally:
npm run build && npx vitest run# Lint and auto-fix
npm run lintESLint is configured with:
@typescript-eslint/eslint-pluginfor TypeScript ruleseslint-plugin-vuefor Vue template rules
# Format all source files
npm run formatPrettier is configured as the formatter. Run it before committing.
- Branch from the latest
master - Keep PRs focused -- one feature or fix per PR
- Write tests for new query builder methods and cache logic
- Run the full check before submitting:
npm run build && npx vitest run - Update documentation if adding new features, configuration options, or views
- Follow existing patterns -- look at similar code in the codebase for conventions
For a detailed understanding of the codebase before contributing, see architecture.md.
Key design principles:
- Instance-agnostic by default -- all queries should work across Wikibase instances unless explicitly gated by
enabledcallbacks - Cache-first -- avoid unnecessary network requests; let users manually refresh when needed
- Graceful degradation -- if a feature is unsupported (e.g., no label service), fall back to a simpler query rather than failing
- Type safety -- leverage TypeScript to catch errors at compile time; avoid
anywhere possible