Rules and patterns for implementing an Elasticsearch DataSource module in Lutece 8. DataSource/DataObject interfaces, CDI auto-discovery, @ConfigProperty injection, batch processing, two-daemon indexing, incremental updates via CDI events. Based on the elasticdata-forms module pattern.
View on GitHubskills/lutece-elasticdata/SKILL.md
February 5, 2026
Select agents to install to:
npx add-skill https://github.com/lutece-platform/lutece-dev-plugin-claude/blob/main/skills/lutece-elasticdata/SKILL.md -a claude-code --skill lutece-elasticdataInstallation paths:
.claude/skills/lutece-elasticdata/# Lutece 8 ElasticData DataSource Module
> Before implementing a DataSource, consult `~/.lutece-references/lutece-form-module-elasticdata-forms/` — the reference implementation. The framework plugin is at `~/.lutece-references/lutece-elk-plugin-elasticdata/` and the HTTP client library at `~/.lutece-references/lutece-elk-library-elastic/`.
## Architecture Overview
```
library-elastic (HTTP/JSON wrapper around Elasticsearch REST API)
↑ used by
plugin-elasticdata (framework — already deployed)
↓ auto-discovers via CDI
module-myentity-elasticdata (@ApplicationScoped DataSource)
↓ produces
MyEntityDataObject (extends AbstractDataObject)
↓ indexed by two daemons
FullIndexingDaemon (daily, bulk reindex)
IncrementalIndexingDaemon (every 3s, processes IndexerAction queue)
Incremental path:
Entity CRUD → CDI event fired
↓ observed by
MyEntityIndexerEventListener (@ObservesAsync)
↓ calls
DataSourceIncrementalService.addTask(dataSourceId, entityId, taskType)
↓ queues in DB → daemon processes
```
A module provides a `DataSource` implementation. The plugin-elasticdata framework handles Elasticsearch communication, daemon scheduling, batch processing, and action queue management.
**CDI auto-discovery** — any `@ApplicationScoped` class implementing `DataSource` is automatically registered:
```java
// Inside DataSourceService (plugin-elasticdata)
CDI.current( ).select( DataSource.class ).stream( )
.forEach( source -> _mapDataSources.put( source.getId( ), source ) );
```
**Three-layer architecture:**
- **library-elastic** — Low-level HTTP client (uses `library-httpaccess`, not the official ES Java client)
- **plugin-elasticdata** — Generic indexing framework (daemons, action queue, bulk API)
- **Your module** — Domain-specific DataSource and DataObject
## Step 1 — Maven Module Setup
```xml
<parent>
<groupId>fr.paris.lutece.plugins</groupId>
<artifactId>lutece-form-module-myentity-elasticdata</artifactId>
</parent>
<dependencies>