How INFINI Console Developer Tools Handles Workspace Management and Command Persistence
INFINI Console's Developer Tools module persists workspaces as Layout documents with type "workspace" via the Layout API, while storing reusable commands as CommonCommand documents in a dedicated Elasticsearch index, both exposed through RESTful endpoints with fine-grained permission controls.
The infinilabs/console repository provides a comprehensive web interface for Elasticsearch operations, with the Developer Tools (DevTools) module enabling users to write, execute, and save queries. This article examines the dual-persistence architecture that powers workspace management and command storage, referencing the actual Go source files and React front-end components that implement these features.
Workspace Management Through the Layout API
The Developer Tools module treats user workspaces as specialized dashboard layouts, leveraging a generic layout management system with a specific type discriminator.
The Workspace Data Model
In model/layout.go, the system defines a constant that identifies workspace layouts:
const (
LayoutTypeWorkspace = "workspace"
)
This constant appears at lines 49-51, distinguishing workspace layouts from other dashboard types. When a user creates a new workspace through the DevTools UI, the front-end sends a POST /layout request to the server. The handler creates a new model.Layout record, populates the Creator and Created fields, and explicitly sets Type = LayoutTypeWorkspace before persistence.
CRUD Operations and Endpoint Registration
The Layout API implements full CRUD functionality in plugin/api/layout/layout.go. Route registration occurs in plugin/api/layout/api.go (lines 41-46), where HTTP verbs bind to handler functions:
// Endpoints include:
// POST /layout - Create workspace
// GET /layout/:id - Retrieve workspace
// PUT /layout/:id - Update workspace
// DELETE /layout/:id - Remove workspace
These handlers utilize the generic ORM helpers—orm.Get, orm.Search, orm.Update, and orm.Delete—to interact with the underlying Elasticsearch storage. Each operation validates permissions against the PermissionLayoutRead and PermissionLayoutWrite constants defined in core/security/enum/const.go.
Index Registration and Storage
The workspace data persists in the layout index, registered during application startup in main.go at line 156. The registration binds the model.Layout struct to the Elasticsearch index, enabling the ORM layer to handle document serialization and query generation automatically.
Command Persistence in Elasticsearch
While workspaces manage UI layouts, the command persistence layer handles the storage and retrieval of reusable Elasticsearch queries.
The CommonCommand Document Structure
Commands are stored as CommonCommand documents, defined in the shared framework package (infini.sh/framework/core/elastic.CommonCommand). The system registers this schema with a custom index name in main.go at line 146:
orm.RegisterSchemaWithIndexName(elastic.CommonCommand{}, "commands")
This registration ensures all command documents route to the dedicated commands index, separate from the workspace layout storage.
Command Lifecycle API Handlers
The file plugin/api/index_management/common_command.go implements four primary handlers that manage the command lifecycle:
HandleAddCommonCommandAction (lines 40-81) processes POST /elasticsearch/command requests. The handler generates a UUID, timestamps the command, validates against duplicate titles, and indexes the document using esClient.Index.
HandleSaveCommonCommandAction (lines 86-127) handles PUT /elasticsearch/command/:cid. This endpoint overwrites existing documents by ID, preserving the command ID while updating the query content and metadata.
HandleQueryCommonCommandAction constructs a query DSL for GET /elasticsearch/command, returning the raw Elasticsearch search response with all saved commands for the current user context.
HandleDeleteCommonCommandAction (lines 130-150) executes DELETE /elasticsearch/command/:cid, removing the document from the index and invalidating the in-memory cache entry simultaneously.
Security and Access Control
Route registration in plugin/api/init.go (lines 65-68) binds these handlers to specific permission constants:
// Permission checks enforced:
// - PermissionCommandRead (for GET operations)
// - PermissionCommandWrite (for POST/PUT/DELETE operations)
These permissions, defined in core/security/enum/const.go, ensure that only authorized users can modify the shared command repository while allowing broader read access for team collaboration.
Front-End Integration and Developer Experience
The React-based front-end bridges user interactions with these back-end services through dedicated service layers and UI components.
DevTools Settings Management
Editor preferences and DevTools configuration reside in web/src/components/vendor/console/services/settings.ts. The DevToolsSettings interface (lines 22-30) defines:
interface DevToolsSettings {
fontSize: number;
autocomplete: boolean;
lineNumbers: boolean;
theme: string;
// Additional Monaco editor configurations
}
The component apply_editor_settings.ts (lines 20-27) consumes these settings to configure the Monaco editor instance used for command editing, applying font sizes, themes, and autocomplete behavior dynamically.
Workspace UI Components
Workspace creation and selection flow through the Dashboard pages in web/src/pages/Insight/Dashboard/. These React components:
- Issue HTTP POST requests to
/layoutwhen users create new workspaces - Send layout metadata including
type: "workspace", name, and description - Handle workspace import/export through the same Layout API endpoints
When users click "Save Command" or "Load Command" in the DevTools interface, the front-end invokes the command API endpoints directly, persisting query text to the commands index and enabling cross-session reuse.
Summary
- Workspaces are stored as
Layoutdocuments withType = "workspace"in thelayoutindex, managed by the Layout API inplugin/api/layout/. - Commands persist as
CommonCommanddocuments in the dedicatedcommandsindex, handled byCommonCommandAPI handlers inplugin/api/index_management/. - Permission controls enforce access through
PermissionCommandRead/WriteandPermissionLayoutRead/Writeconstants. - Front-end integration occurs via React components in
web/src/components/vendor/console/andweb/src/pages/Insight/Dashboard/, communicating with RESTful endpoints to provide seamless query management.
Frequently Asked Questions
What Elasticsearch indices store workspace and command data?
Workspaces reside in the layout index, registered in main.go at line 156. Commands reside in the commands index, registered at line 146 via orm.RegisterSchemaWithIndexName(elastic.CommonCommand{}, "commands").
How does the system prevent duplicate command titles?
The HandleAddCommonCommandAction handler in plugin/api/index_management/common_command.go (lines 40-81) validates the command title against existing documents before indexing. If a duplicate title exists within the user context, the API returns an error before the esClient.Index operation executes.
Which permissions control access to Developer Tools features?
The system defines four relevant permissions in core/security/enum/const.go: PermissionCommandRead and PermissionCommandWrite for query management, plus PermissionLayoutRead and PermissionLayoutWrite for workspace operations. These are enforced during route registration in plugin/api/init.go.
Where is the Monaco editor configuration applied?
The DevToolsSettings interface in web/src/components/vendor/console/services/settings.ts stores editor preferences. The apply_editor_settings.ts component (lines 20-27) applies these configurations to the Monaco editor instance, controlling font size, themes, and autocomplete behavior in the DevTools query interface.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →