ADR-020: Community DevOps Best Practices Integration

Status

Proposed

Date

2024-12-07

Deciders

Context and Problem Statement

The iDempiere community has developed several mature DevOps tools maintained by core developers:

These tools represent years of accumulated best practices but are scattered across repositories, use different interfaces (bash scripts, property files), and require manual coordination. The idempiere-cli can serve as a unified interface to these capabilities, providing a consistent developer experience.

Decision Drivers

Considered Options

  1. Full Integration - Reimplement all functionality natively in Java
  2. Wrapper Integration - CLI wraps existing scripts with unified interface
  3. Reference Documentation - Just document how to use existing tools
  4. Hybrid Approach - Native implementation of core features, wrappers for specialized tools

Decision Outcome

Chosen option: "Hybrid Approach", because it provides immediate value through native implementations of high-value features while maintaining compatibility with existing community scripts through optional wrapper integration.

Confirmation

Analysis of Community Tools

1. hengsin/idempiere-dev-setup

Purpose: Automated iDempiere development environment setup

Key Features:

Feature CLI Relevance Priority
Git clone + Maven build Already have ide init Low
Eclipse workspace setup High value, complex Medium
Docker PostgreSQL High demand High
Database initialization Already have server db Low
Branch management Useful for version switching Medium
Target platform config Eclipse-specific Low

Proposed Commands:

ide setup dev              # Full dev environment wizard
ide setup docker-postgres  # Create PostgreSQL container
ide setup eclipse-ws       # Configure Eclipse workspace

2. chuboe/idempiere-installation-script

Purpose: Production iDempiere server deployment

Key Features:

Feature CLI Relevance Priority
PostgreSQL installation Server setup Medium
iDempiere deployment Download + configure High
Systemd service Service management High
PostgreSQL tuning Performance optimization Medium
SSL certificates Security setup Medium
S3 backup config Backup automation Medium
Replication setup HA configuration Low

Proposed Commands:

server install            # Production server installer
server service create     # Create systemd service
server service status     # Check service status
server tune postgres      # Apply PostgreSQL optimizations
server ssl setup          # Generate/configure SSL
server backup configure   # Configure backup strategy

3. chuboe/chuboe-system-configurator

Purpose: Server administration standardization

Key Features:

Feature CLI Relevance Priority
Shell configurations Out of scope None
PostgreSQL client config Useful .pgpass setup Low
Backup scripts Backup automation Medium
tmux/vim configs Out of scope None

Proposed Commands:

server backup schedule    # Setup automated backups
server backup run         # Execute backup now
server backup restore     # Restore from backup

4. globalqss/idempiere-stuff

Purpose: Database utilities and CI/CD automation

Key Features:

Feature CLI Relevance Priority
Database validation Schema verification High
Client backup/delete Multi-tenant ops High
Foreign key generation DB maintenance Medium
Record ID validation Data integrity Medium
Jenkins scripts CI/CD integration Medium
PR verification QA automation Low

Proposed Commands:

db validate               # Compare DB vs Application Dictionary
db validate-records       # Validate record IDs
db client backup          # Backup specific client
db client delete          # Delete client (with safety)
db generate-fk            # Generate missing foreign keys

Implementation Roadmap

Phase 0: Database Performance Commands (Critical Priority)

Rationale: Database performance degrades significantly as data grows. Production iDempiere systems with millions of records suffer from:

These commands provide immediate, measurable performance improvements.

0.1 Index Management

db index validate              # Compare AD_TableIndex vs actual DB indexes
db index create-missing        # Create indexes defined in AD but missing in DB
db index recommend             # Suggest indexes based on slow query analysis
db index unused                # Find indexes that are never used (candidates for removal)

Implementation SQL (PostgreSQL):

-- Find AD_TableIndex definitions without corresponding DB indexes
SELECT ti.name AS index_name,
       t.tablename,
       ti.isunique,
       string_agg(ic.columnname, ', ' ORDER BY ic.seqno) AS columns
FROM ad_tableindex ti
JOIN ad_table t ON ti.ad_table_id = t.ad_table_id
JOIN ad_indexcolumn ic ON ti.ad_tableindex_id = ic.ad_tableindex_id
JOIN ad_column c ON ic.ad_column_id = c.ad_column_id
WHERE ti.isactive = 'Y'
  AND NOT EXISTS (
    SELECT 1 FROM pg_indexes
    WHERE indexname = lower(ti.name)
  )
GROUP BY ti.name, t.tablename, ti.isunique;

Reference: Create Table Index (Process ID-200057)

0.2 Foreign Key Generation

db fk validate                 # Show missing FKs based on AD_Reference
db fk generate --dry-run       # Preview ALTER TABLE statements
db fk generate --apply         # Create missing foreign keys

Implementation: Port globalqss generateForeignKeys_pg.sql

Foreign keys provide:

SQL Logic:

-- Find columns that should have FK but don't (AD_Reference types 18, 19, 30)
SELECT t.tablename AS source_table,
       c.columnname AS source_column,
       rt.tablename AS target_table,
       'ALTER TABLE ' || t.tablename ||
       ' ADD CONSTRAINT ' || substr(c.columnname || '_' || t.tablename, 1, 30) ||
       ' FOREIGN KEY (' || c.columnname || ') REFERENCES ' || rt.tablename ||
       ' DEFERRABLE INITIALLY DEFERRED;' AS ddl
FROM ad_column c
JOIN ad_table t ON c.ad_table_id = t.ad_table_id
JOIN ad_reference r ON c.ad_reference_id = r.ad_reference_id
LEFT JOIN ad_ref_table rft ON c.ad_reference_value_id = rft.ad_reference_id
LEFT JOIN ad_table rt ON rft.ad_table_id = rt.ad_table_id
WHERE c.ad_reference_id IN (18, 19, 30)  -- Table, TableDirect, Search
  AND t.isview = 'N'
  AND c.columnname NOT IN ('AD_Client_ID', 'AD_Org_ID', 'CreatedBy', 'UpdatedBy')
  AND NOT EXISTS (
    SELECT 1 FROM pg_constraint pc
    JOIN pg_class cls ON pc.conrelid = cls.oid
    WHERE pc.contype = 'f'
      AND cls.relname = lower(t.tablename)
      AND pc.conname LIKE '%' || lower(c.columnname) || '%'
  );

0.3 Table Health Analysis

db health bloat                # Show table/index bloat statistics
db health vacuum [TABLE]       # Run VACUUM on table(s)
db health vacuum-full [TABLE]  # Run VACUUM FULL (reclaim disk space)
db health analyze [TABLE]      # Update table statistics
db health reindex [TABLE]      # Rebuild indexes
db health autovacuum-status    # Check autovacuum configuration and activity

Implementation SQL:

-- Table bloat analysis
SELECT schemaname, relname AS table_name,
       pg_size_pretty(pg_total_relation_size(relid)) AS total_size,
       n_live_tup AS live_rows,
       n_dead_tup AS dead_rows,
       CASE WHEN n_live_tup > 0
            THEN round(n_dead_tup * 100.0 / n_live_tup, 2)
            ELSE 0 END AS dead_pct,
       last_vacuum,
       last_autovacuum,
       last_analyze
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY n_dead_tup DESC
LIMIT 20;

-- Index bloat estimation
SELECT schemaname, tablename, indexname,
       pg_size_pretty(pg_relation_size(indexrelid)) AS index_size,
       idx_scan AS times_used,
       idx_tup_read,
       idx_tup_fetch
FROM pg_stat_user_indexes
ORDER BY pg_relation_size(indexrelid) DESC
LIMIT 20;

Reference: PostgreSQL VACUUM Best Practices

0.4 PostgreSQL Auto-Tuning

db tune recommend              # Show recommended postgresql.conf settings
db tune apply                  # Apply settings (requires restart)
db tune current                # Show current vs recommended values

Implementation: Use pgconfig.org API or embedded tuning rules.

Tuning Parameters by System Memory:

Parameter 8GB 16GB 32GB 64GB
shared_buffers 2GB 4GB 8GB 16GB
effective_cache_size 6GB 12GB 24GB 48GB
maintenance_work_mem 512MB 1GB 2GB 2GB
work_mem 16MB 32MB 64MB 128MB
wal_buffers 64MB 64MB 64MB 64MB
max_connections 100 200 300 400
random_page_cost 1.1 1.1 1.1 1.1

Autovacuum Tuning (critical for large tables):

-- Per-table autovacuum settings for high-transaction tables
ALTER TABLE c_orderline SET (
    autovacuum_vacuum_scale_factor = 0.01,   -- 1% instead of 20%
    autovacuum_analyze_scale_factor = 0.005,
    autovacuum_vacuum_cost_limit = 1000
);

0.5 Slow Query Analysis & EXPLAIN

db queries slow [--threshold 1s]     # Show queries exceeding threshold
db queries frequent [--limit 20]     # Most frequently executed queries
db queries explain <SQL|file>        # EXPLAIN ANALYZE for a query
db queries explain --format json     # JSON format for visualization tools
db queries auto-explain enable       # Enable automatic EXPLAIN logging
db queries enable-stats              # Enable pg_stat_statements extension
db queries log-settings              # Show/configure log_min_duration_statement

Requires: pg_stat_statements and auto_explain extensions

-- Enable extensions
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
LOAD 'auto_explain';

-- Find slow queries
SELECT round(total_exec_time::numeric, 2) AS total_ms,
       calls,
       round(mean_exec_time::numeric, 2) AS avg_ms,
       round(stddev_exec_time::numeric, 2) AS stddev_ms,
       rows,
       query
FROM pg_stat_statements
WHERE mean_exec_time > 1000  -- > 1 second average
ORDER BY total_exec_time DESC
LIMIT 20;

EXPLAIN ANALYZE Command:

db queries explain "SELECT * FROM c_order WHERE c_bpartner_id = 123"
db queries explain --file problematic_query.sql
db queries explain --format json --buffers --timing "SELECT ..."

Implementation:

-- Full EXPLAIN with all metrics
EXPLAIN (ANALYZE, BUFFERS, TIMING, COSTS, VERBOSE, FORMAT JSON)
SELECT o.documentno, ol.line, p.name
FROM c_order o
JOIN c_orderline ol ON o.c_order_id = ol.c_order_id
JOIN m_product p ON ol.m_product_id = p.m_product_id
WHERE o.dateordered > '2024-01-01';

Output Analysis (CLI parses and highlights):

┌─────────────────────────────────────────────────────────────────────┐
│ Query Plan Analysis                                                  │
├─────────────────────────────────────────────────────────────────────┤
│ Total Time: 2,345 ms                                                │
│ Planning Time: 12 ms                                                │
│ Execution Time: 2,333 ms                                            │
├─────────────────────────────────────────────────────────────────────┤
│ ⚠ WARNINGS:                                                         │
│   • Seq Scan on c_order (cost=0..15234) - Missing index?           │
│   • Nested Loop (actual rows=50000) - Consider Hash Join           │
│   • Buffers shared read=12456 - High I/O, increase shared_buffers  │
├─────────────────────────────────────────────────────────────────────┤
│ RECOMMENDATIONS:                                                     │
│   1. CREATE INDEX idx_c_order_dateordered ON c_order(dateordered); │
│   2. Run ANALYZE c_order; (stats may be stale)                     │
│   3. Consider increasing work_mem for this session                  │
└─────────────────────────────────────────────────────────────────────┘

Auto-Explain Configuration (for automatic logging):

-- In postgresql.conf or via ALTER SYSTEM
ALTER SYSTEM SET auto_explain.log_min_duration = '1s';
ALTER SYSTEM SET auto_explain.log_analyze = true;
ALTER SYSTEM SET auto_explain.log_buffers = true;
ALTER SYSTEM SET auto_explain.log_timing = true;
ALTER SYSTEM SET auto_explain.log_nested_statements = true;

-- Enable for session (no restart needed)
SET auto_explain.log_min_duration = '1s';
SET auto_explain.log_analyze = true;

Integration with iDempiere Logs:

db queries from-log /path/to/idempiere.log   # Extract SQLs from server log
db queries from-log --slow-only              # Only queries marked slow

The CLI can parse iDempiere server logs to extract SQL statements and automatically run EXPLAIN ANALYZE on them.

0.6 Anomaly Detection

db monitor baseline                  # Establish baseline metrics (run for 24-48h)
db monitor anomalies                 # Detect current anomalies vs baseline
db monitor watch [--interval 60s]    # Continuous monitoring (stdout)
db monitor report [--period 7d]      # Historical anomaly report

What Gets Monitored:

Metric Baseline Anomaly Threshold Alert Level
Query execution time avg ± stddev > 3× stddev Warning
Query execution time avg ± stddev > 10× stddev Critical
Queries per second avg ± stddev > 5× normal Warning
Connection count avg ± stddev > 80% max_connections Critical
Dead tuples growth daily rate > 10× normal rate Warning
Table size growth weekly rate > 5× normal rate Warning
Lock wait time avg > 30 seconds Critical
Blocked queries count > 5 concurrent Critical

Implementation:

-- Establish baseline (store in cli metadata table or local file)
CREATE TABLE IF NOT EXISTS idempiere_cli_baseline (
    metric_name VARCHAR(100),
    measured_at TIMESTAMP DEFAULT now(),
    avg_value NUMERIC,
    stddev_value NUMERIC,
    min_value NUMERIC,
    max_value NUMERIC,
    sample_count INTEGER
);

-- Capture baseline for query times
INSERT INTO idempiere_cli_baseline (metric_name, avg_value, stddev_value, min_value, max_value, sample_count)
SELECT 'query_exec_time',
       avg(mean_exec_time),
       stddev(mean_exec_time),
       min(mean_exec_time),
       max(mean_exec_time),
       count(*)
FROM pg_stat_statements
WHERE calls > 10;

-- Detect anomalies: queries running 3× slower than baseline
WITH baseline AS (
    SELECT avg_value, stddev_value
    FROM idempiere_cli_baseline
    WHERE metric_name = 'query_exec_time'
    ORDER BY measured_at DESC LIMIT 1
)
SELECT query,
       round(mean_exec_time::numeric, 2) AS current_avg_ms,
       round(b.avg_value::numeric, 2) AS baseline_avg_ms,
       round((mean_exec_time / NULLIF(b.avg_value, 0))::numeric, 1) AS times_slower,
       CASE
           WHEN mean_exec_time > b.avg_value + (10 * b.stddev_value) THEN 'CRITICAL'
           WHEN mean_exec_time > b.avg_value + (3 * b.stddev_value) THEN 'WARNING'
           ELSE 'OK'
       END AS status
FROM pg_stat_statements, baseline b
WHERE mean_exec_time > b.avg_value + (3 * b.stddev_value)
ORDER BY mean_exec_time DESC;

Real-Time Spike Detection:

-- Detect queries that suddenly spiked (last hour vs last 24h)
WITH recent AS (
    SELECT queryid, query,
           mean_exec_time AS recent_time,
           calls AS recent_calls
    FROM pg_stat_statements
),
historical AS (
    -- Compare with stored snapshot from 24h ago
    SELECT queryid, mean_exec_time AS historical_time
    FROM idempiere_cli_query_snapshot
    WHERE snapshot_time > now() - interval '24 hours'
)
SELECT r.query,
       round(r.recent_time::numeric, 2) AS current_ms,
       round(h.historical_time::numeric, 2) AS yesterday_ms,
       round((r.recent_time / NULLIF(h.historical_time, 0))::numeric, 1) AS spike_factor
FROM recent r
JOIN historical h ON r.queryid = h.queryid
WHERE r.recent_time > h.historical_time * 3  -- 3× slower
ORDER BY spike_factor DESC;

Long-Running Query Detection (real-time):

-- Queries running longer than threshold
SELECT pid,
       now() - query_start AS duration,
       state,
       wait_event_type,
       wait_event,
       left(query, 100) AS query_preview,
       CASE
           WHEN now() - query_start > interval '10 minutes' THEN 'CRITICAL'
           WHEN now() - query_start > interval '5 minutes' THEN 'WARNING'
           ELSE 'INFO'
       END AS alert_level
FROM pg_stat_activity
WHERE state = 'active'
  AND query NOT LIKE '%pg_stat%'
  AND now() - query_start > interval '1 minute'
ORDER BY duration DESC;

Lock Contention Detection:

-- Detect blocking chains
SELECT blocked.pid AS blocked_pid,
       blocked.query AS blocked_query,
       blocking.pid AS blocking_pid,
       blocking.query AS blocking_query,
       now() - blocked.query_start AS wait_duration
FROM pg_stat_activity blocked
JOIN pg_locks blocked_locks ON blocked.pid = blocked_locks.pid
JOIN pg_locks blocking_locks ON blocked_locks.locktype = blocking_locks.locktype
    AND blocked_locks.relation = blocking_locks.relation
    AND blocked_locks.pid != blocking_locks.pid
JOIN pg_stat_activity blocking ON blocking_locks.pid = blocking.pid
WHERE NOT blocked_locks.granted
  AND blocking_locks.granted;

CLI Output Example:

$ idempiere-cli db monitor anomalies

╔══════════════════════════════════════════════════════════════════════╗
║                    DATABASE ANOMALY REPORT                            ║
║                    2024-12-07 14:32:15                                ║
╠══════════════════════════════════════════════════════════════════════╣
║ 🔴 CRITICAL ALERTS (2)                                                ║
╠══════════════════════════════════════════════════════════════════════╣
║ Query Spike: SELECT * FROM c_invoice WHERE ...                       ║
║   Current: 12,450 ms | Baseline: 245 ms | 50.8× slower              ║
║   Recommendation: Check for missing index on c_invoice.dateacct      ║
║                                                                      ║
║ Long Running: PID 28451 running for 18 minutes                       ║
║   Query: UPDATE m_storageonhand SET qtyonhand = ...                  ║
║   Waiting on: transactionid lock (PID 28320)                         ║
╠══════════════════════════════════════════════════════════════════════╣
║ ⚠️  WARNINGS (3)                                                      ║
╠══════════════════════════════════════════════════════════════════════╣
║ Connection Spike: 156/200 connections (78% - approaching limit)      ║
║ Dead Tuple Growth: c_orderline has 2.3M dead tuples (45% of table)  ║
║ Query Frequency: Invoice report running 340×/hour (normal: 12×)     ║
╠══════════════════════════════════════════════════════════════════════╣
║ ✅ HEALTHY METRICS                                                    ║
║   • Cache hit ratio: 99.2% (good > 95%)                              ║
║   • Index usage: 98.7% (good > 95%)                                  ║
║   • Checkpoint frequency: normal                                      ║
╚══════════════════════════════════════════════════════════════════════╝

Watch Mode (continuous monitoring):

$ idempiere-cli db monitor watch --interval 30s

[14:32:15] Monitoring... (Ctrl+C to stop)
[14:32:45] ✅ All metrics normal
[14:33:15] ✅ All metrics normal
[14:33:45] ⚠️  Query spike detected: c_invoice SELECT (3.2× baseline)
[14:34:15] 🔴 CRITICAL: Query now 8.5× baseline
[14:34:45] ⚠️  Query returning to normal (2.1× baseline)

Output Formats (for external monitoring integration):

db monitor anomalies --format json           # JSON for log aggregators
db monitor anomalies --format prometheus     # Prometheus metrics
db monitor watch --format json               # Stream JSON events

0.7 Notification & Logging Integration

Status: NOT PLANNED - Notification/alerting is better handled by external monitoring infrastructure (Prometheus/Grafana/AlertManager) rather than built into a CLI tool.

Alternative approach: CLI provides JSON output that can be consumed by existing monitoring tools:

db health bloat --format json | jq .      # Pipe to monitoring
db queries slow --format json             # Export for analysis
db monitor anomalies --format prometheus  # Prometheus metrics format

For future consideration: A Prometheus exporter endpoint (db metrics serve --port 9090) could provide metrics for external monitoring systems.

0.8 Connection Pool Analysis

db connections active          # Show active connections
db connections idle            # Show idle connections
db connections blocked         # Show blocked/waiting queries
db connections kill <pid>      # Terminate a connection
-- Connection overview
SELECT state, usename, application_name,
       client_addr, count(*)
FROM pg_stat_activity
WHERE datname = current_database()
GROUP BY state, usename, application_name, client_addr;

-- Long-running queries
SELECT pid, now() - pg_stat_activity.query_start AS duration,
       query, state
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes'
  AND state != 'idle';

Phase 1: High-Priority Native Commands

Commands to implement natively in Java:

1.1 Docker PostgreSQL Setup

ide docker postgres create [--name NAME] [--version VERSION] [--port PORT]
ide docker postgres start
ide docker postgres stop

Implementation: Use ProcessBuilder to execute Docker commands, similar to existing patterns in the codebase.

Reference: hengsin/idempiere-dev-setup/docker-postgres.sh

1.2 Database Validation

db validate [--fix] [--client ID]

Implementation: Execute SQL queries comparing AD_Column/AD_Table against information_schema. Already have database connectivity in JdbcTemplateService.

Reference: globalqss/idempiere-stuff/CheckDatabaseVsDictionary.sql

1.3 Client Backup/Delete

db client backup --client-id ID --output FILE
db client delete --client-id ID [--confirm]

Implementation: Port SQL scripts to parameterized queries with safety checks.

Reference:

1.4 Service Management

server service create [--user USER] [--memory MEMORY]
server service start
server service stop
server service status

Implementation: Generate systemd unit files from templates, execute systemctl commands.

Reference: chuboe/idempiere-installation-script service setup

Phase 2: Medium-Priority Commands

2.1 PostgreSQL Performance Tuning

server tune postgres [--memory SIZE] [--connections N] [--apply]

Implementation: Use pgconfig.org API or embedded tuning rules to generate postgresql.conf recommendations.

2.2 Backup Configuration

server backup configure --destination (local|s3|rsync) [--schedule CRON]
server backup run [--type full|incremental]
server backup list
server backup restore --from BACKUP

2.3 SSL Setup

server ssl generate --domain DOMAIN
server ssl install --cert FILE --key FILE

Phase 3: Wrapper Integration

For complex tools that don't warrant reimplementation:

ide external dev-setup [ARGS...]     # Wraps hengsin/idempiere-dev-setup
ide external install [ARGS...]       # Wraps chuboe/idempiere-installation-script

Implementation: Clone repositories to ~/.idempiere-cli/external/, forward arguments to scripts.

Command Structure Integration

Integrate with existing command hierarchy (per ADR-019):

idempiere-cli
├── ide
│   ├── init              # Existing
│   ├── setup             # NEW: Dev environment setup
│   │   ├── dev           # Full wizard
│   │   ├── docker-postgres
│   │   └── eclipse-ws
│   └── external          # NEW: Wrapper commands
│       ├── dev-setup
│       └── install
├── server
│   ├── db                # Existing
│   ├── install           # NEW: Production installer
│   ├── service           # NEW: Systemd management
│   │   ├── create
│   │   ├── start
│   │   ├── stop
│   │   └── status
│   ├── tune              # NEW: Performance tuning
│   │   └── postgres
│   ├── ssl               # NEW: SSL management
│   │   ├── generate
│   │   └── install
│   └── backup            # NEW: Backup management
│       ├── configure
│       ├── run
│       ├── list
│       └── restore
└── db                    # NEW command group
    ├── validate          # Schema vs AD validation
    ├── validate-records  # Record ID validation
    ├── index             # NEW: Index management
    │   ├── validate      # AD_TableIndex vs actual
    │   ├── create-missing
    │   ├── recommend
    │   └── unused
    ├── fk                # NEW: Foreign key management
    │   ├── validate
    │   └── generate
    ├── health            # NEW: Database health
    │   ├── bloat
    │   ├── vacuum
    │   ├── vacuum-full
    │   ├── analyze
    │   ├── reindex
    │   └── autovacuum-status
    ├── tune              # NEW: PostgreSQL tuning
    │   ├── recommend
    │   ├── apply
    │   └── current
    ├── queries           # NEW: Query analysis
    │   ├── slow
    │   ├── frequent
    │   ├── explain
    │   ├── auto-explain
    │   ├── from-log
    │   └── enable-stats
    ├── monitor           # NEW: Anomaly detection
    │   ├── baseline      # Establish normal metrics
    │   ├── anomalies     # Detect current anomalies
    │   ├── watch         # Continuous monitoring (stdout/JSON)
    │   └── report        # Historical report
    ├── connections       # NEW: Connection management
    │   ├── active
    │   ├── idle
    │   ├── blocked
    │   └── kill
    └── client            # Multi-tenant operations
        ├── backup
        └── delete

Pros and Cons of the Options

Option 1: Full Integration

Reimplement everything in Java

Option 2: Wrapper Integration

CLI just wraps existing bash scripts

Option 3: Reference Documentation

Just document existing tools

Option 4: Hybrid Approach (Chosen)

Native core features + optional wrappers

Implementation Notes

Native Command Template

@Command(name = "validate",
         description = "Validate database schema against Application Dictionary")
public class DbValidateCommand implements Callable<Integer> {

    @Option(names = "--fix", description = "Attempt to fix discrepancies")
    boolean fix;

    @Option(names = "--client", description = "Validate specific client")
    Integer clientId;

    @Inject
    JdbcTemplateService jdbc;

    @Override
    public Integer call() {
        // Reference: globalqss/idempiere-stuff/CheckDatabaseVsDictionary.sql
        String sql = """
            SELECT c.columnname, c.ad_column_id,
                   CASE WHEN col.column_name IS NULL THEN 'Missing'
                        ELSE 'OK' END as status
            FROM ad_column c
            JOIN ad_table t ON c.ad_table_id = t.ad_table_id
            LEFT JOIN information_schema.columns col
                   ON lower(t.tablename) = col.table_name
                  AND lower(c.columnname) = col.column_name
            WHERE t.isview = 'N' AND c.isactive = 'Y'
            ORDER BY t.tablename, c.columnname
            """;
        // Execute and report...
    }
}

Attribution Guidelines

Every command derived from community tools must:

  1. Reference the original tool in description annotation
  2. Include URL in --help extended description
  3. Document in USER_GUIDE.md with credits

Example:

@Command(name = "docker-postgres",
         description = "Create PostgreSQL Docker container",
         footer = "%nBased on: https://github.com/hengsin/idempiere-dev-setup")

References

Community Tools

iDempiere Documentation

PostgreSQL Performance


Appendix: Feature Mapping Matrix

Phase 0: Database Performance (Critical Priority)

Feature Source CLI Command Impact Status
Missing index detection AD_TableIndex db index validate Critical Proposed
Index creation from AD AD_TableIndex db index create-missing Critical Proposed
Index recommendations pg_stat_statements db index recommend High Proposed
Unused index detection pg_stat_user_indexes db index unused Medium Proposed
FK validation AD_Reference db fk validate Critical Proposed
FK generation globalqss/stuff db fk generate Critical Proposed
Table bloat analysis pg_stat_user_tables db health bloat Critical Proposed
VACUUM execution PostgreSQL db health vacuum Critical Proposed
Statistics update PostgreSQL db health analyze High Proposed
Index rebuild PostgreSQL db health reindex High Proposed
Autovacuum monitoring pg_stat db health autovacuum-status High Proposed
PostgreSQL tuning chuboe/pgconfig db tune recommend Critical Proposed
Slow query detection pg_stat_statements db queries slow Critical Proposed
EXPLAIN ANALYZE PostgreSQL db queries explain Critical Proposed
Auto-explain setup auto_explain db queries auto-explain High Proposed
Log SQL extraction iDempiere logs db queries from-log High Proposed
Baseline establishment pg_stat_* db monitor baseline Critical Proposed
Anomaly detection Statistical analysis db monitor anomalies Critical Proposed
Continuous monitoring pg_stat_* db monitor watch Critical Proposed
Spike detection Time-series compare db monitor anomalies Critical Proposed
Lock contention detection pg_locks db monitor watch High Proposed
Connection monitoring pg_stat_activity db connections * High Proposed
JSON/Prometheus output Built-in --format json/prometheus High Proposed

Phase 1-3: DevOps Integration

Community Feature Source Repository CLI Command Priority Status
Docker PostgreSQL hengsin/dev-setup ide setup docker-postgres High Proposed
Eclipse workspace hengsin/dev-setup ide setup eclipse-ws Medium Proposed
Branch management hengsin/dev-setup ide setup dev --branch Medium Proposed
Server installation chuboe/install server install High Proposed
Systemd service chuboe/install server service * High Proposed
SSL certificates chuboe/install server ssl * Medium Proposed
S3 backup chuboe/install server backup * Medium Proposed
DB validation globalqss/stuff db validate High Proposed
Client backup globalqss/stuff db client backup High Proposed
Client delete globalqss/stuff db client delete High Proposed
Record validation globalqss/stuff db validate-records Medium Proposed

Appendix: Community Tool Comparison

Aspect hengsin/dev-setup chuboe/install chuboe/config globalqss/stuff
Focus Development Production Administration Utilities
Platform Linux (WSL) Ubuntu Any Linux Any
Interface Bash + GUI Bash Bash SQL + Bash
DB Support PG + Oracle PostgreSQL Any PG + Oracle
Maintenance Active Active Active Moderate
Documentation README Website README Minimal

Path: /docs/developers/architecture/idempiere-hub/020-community-devops-integration