Ctrl K
ComunidadGuías…

AGENTS.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Datashare Client is a Vue 3 web application for document search and analysis, part of the ICIJ Datashare ecosystem. It provides a frontend interface for searching, viewing, and analyzing documents with features like batch search, named entity recognition, and customizable insights.

## Development Commands

### Essential Commands

```bash
# Install dependencies
yarn

# Start dev server with hot reload at localhost:9009
yarn serve

# Build for production
yarn build

# Run all unit tests
yarn test

# Run tests in watch mode
yarn test:unit:watch

# Lint all files
yarn lint

# Lint and auto-fix
yarn lint:fix

# Lint only modified files (git diff)
yarn lint:modified
```

### Documentation & Storybook

```bash
# Generate all documentation
yarn doc

# Run Storybook dev server on port 6006
yarn storybook

# Individual doc generators
yarn doc:api        # Generate API docs from JSDoc
yarn doc:hooks      # Generate hooks documentation
yarn doc:widgets    # Generate widgets documentation
yarn doc:storybook  # Build static Storybook
```

### Running with Backend

The client requires the Datashare backend running on port 8080 with CORS enabled:

```bash
datashare --tcpListenPort 8080
```

The dev server proxies API requests (`/api`, `/settings`, `/me`, `/auth`, `/version`) to `VITE_DEV_PROXY` environment variable (defaults to backend).

## Architecture

### Core Application Pattern

The application uses a **Core class pattern** (not a standard Vue pattern) that extends multiple mixins to provide plugin-like functionality:

- **Core** (`src/core/Core.js`): Central application class that orchestrates Vue app, router, state management, and plugins
- **Mixins**: Functional composition pattern that adds capabilities to Core
  - `ComponentsMixin`: Dynamic component registration
  - `FiltersMixin`: Search filter management
  - `HooksMixin`: Extension points for injecting components
  - `I18nMixin`: Internationalization helpers
  - `PipelinesMixin`: Data transformation pipelines
  - `ProjectsMixin`: Multi-project management
  - `WidgetsMixin`: Dashboard widget system

### State Management (Pinia)

All stores are located in `src/store/modules/`:
- `search.js`: Search queries, filters, and results
- `document.js`: Current document state
- `hooks.js`: Registered hook components
- `insights.js`: Dashboard widgets
- `task.js`: Background task monitoring
- And 12+ other domain-specific stores

Access stores via `core.stores.useSearchStore()` in components.

### Plugin Systems

**Hooks** allow injecting Vue components at predefined plugin points:

```javascript
// Register a hook
core.registerHook({
  target: 'document.header',  // Plugin point identifier
  name: 'my-custom-component',
  order: 10,                   // Lower = renders first
  definition: MyComponent
})
```

**Widgets** extend the Insights dashboard:

```javascript
// Register a widget
core.registerWidget({
  name: 'my-widget',
  type: 'WidgetText',
  title: 'My Widget',
  cols: 6,  // Bootstrap grid columns (1-12)
  card: true
})
```

### Routing & Authentication

- **Router**: Vue Router with hash history mode (`src/router/index.js`)
- **Guards**: Route protection in `src/router/guards/`
- **Modes**: Three authentication modes defined in `src/mode/index.js`:
  - `LOCAL`: Standalone with document management
  - `EMBEDDED`: Embedded mode with document management
  - `SERVER`: Server-authenticated without document management

### API Layer

- **Api class** (`src/api/index.js`): Axios-based HTTP client for backend communication
- **Elasticsearch** (`src/api/elasticsearch.js`): Direct Elasticsearch queries for search
- **Resources**: API resource classes in `src/api/resources/`

## Testing

### Test Structure

```
tests/unit/
  ├── api_mock.js       # Mock API responses
  ├── CoreSetup.js      # Test helper to create Core instances
  ├── setup.js          # Vitest global setup
  └── specs/            # Test files (134 spec files)
      ├── core/
      ├── components/
      └── store/
```

### Running Specific Tests

```bash
# Run tests matching pattern
yarn test <pattern>

# Examples:
yarn test search           # Tests with "search" in filename
yarn test SearchBar        # Specific component tests
```

### Writing Tests

- Use `CoreSetup` helper to create isolated Core instances
- Mock API with `api_mock.js`
- Tests run in jsdom environment (configured in `vitest.config.js`)

## Build System (Vite)

### Key Configuration

- **Auto-imports**: Phosphor icons and BootstrapVue components are auto-imported
- **Aliases**:
  - `@/` → `src/`
  - `~mixins` → `src/mixins`
  - `~tests` → `tests/`
  - `~storybook` → `.storybook/`
- **SCSS**: Global styles in `src/utils/settings.scss` are auto-imported
- **Dev Server**: Port 9009, proxies backend requests

### Environment Variables

Prefix with `VITE_` to expose to client code:
- `VITE_BASE`: Base path for deployment
- `VITE_DEV_PROXY`: Backend URL for dev proxy
- `VITE_DS_PREVIEW_HOST`: Document preview host

## Component Structure

Components follow a modular structure in `src/components/`:
- Each major feature has its own directory
- Reusable components are standalone
- Storybook stories in `src/stories/` mirror component structure

### Component Naming

- Components: PascalCase (e.g., `DocumentCard.vue`)
- Composables: `use*` pattern in `src/composables/`
- Stores: `use*Store()` pattern

## Styling

- **Bootstrap 5** via `bootstrap-vue-next`
- **ICIJ Murmur**: Design system library (`@icij/murmur`)
- **SCSS**: Preprocessor with global settings
- **Theme**: Supports light/dark mode via `useTheme` composable

## Linting

Uses ICIJ shared ESLint config (`@icij/eslint-config`) with:
- Vue plugin
- TypeScript support
- Stylistic rules
- Vitest plugin
- Storybook plugin

## Important Files

- `src/core/index.js`: Core initialization and export
- `src/main.js`: Application entry point
- `src/router/index.js`: Route definitions
- `src/store/pinia.js`: Pinia instance configuration
- `src/utils/settings.js`: Default application settings
- `vite.config.js`: Build and dev server configuration
- `vitest.config.js`: Test configuration

## Code Patterns

### Accessing Core in Components

Use the `useCore()` composable to access the core instance:

```javascript
import { useCore } from '@/composables/useCore'

// In component setup
const core = useCore()

// Access API
core.api.getSettings()

// Access stores
core.stores.useSearchStore()

// Access router
core.router.push('/documents')
```

### Event Bus

Global event bus for cross-component communication:

```javascript
// Emit event
core.emit('document:loaded', { id: '123' })

// Listen to event
core.on('document:loaded', (payload) => { ... })

// Remove listener
core.off('document:loaded', handler)
```

### Toast Notifications

Use the `useToast()` composable for toast notifications:

```javascript
import { useToast } from '@/composables/useToast'

// In component setup
const { toast } = useToast()

// Show notifications
toast.success('Operation completed')
toast.error('Something went wrong')
toast.warning('Warning message')
toast.info('Information message')
```

### Toasted Promises

The `useToast` composable provides a `toastedPromise` helper that automatically shows success/error toasts:

```javascript
import { useToast } from '@/composables/useToast'

const { toastedPromise } = useToast()

toastedPromise(
  api.saveDocument(data),
  {
    successMessage: 'Document saved!',
    errorMessage: 'Failed to save document'
  }
)
```

## Multi-Project Support

The application supports multiple document collections ("projects"):
- Current project stored in search store
- Switch projects to change active document collection
- Each project can have isolated hooks and widgets
- Use `registerHookForProject()` and `registerWidgetForProject()` for project-specific extensions