CodeVibers case studies Plan the rollout

Internal ERP platform: internal system as a product

CodeVibers’ internal ERP system isn’t just a tool—it’s a potential product. We explore how to take it beyond the company while preserving flexibility, security, and speed.

What is “internal system as a product”?

This approach involves designing and developing an internal IT system (e.g., ERP, CRM, warehouse automation) not only to meet the company’s current needs but also with potential commercialization in mind—enabling API exposure, modularity, documentation, access control, and scalable architecture. In CodeVibers’ case, an ERP system originally built for managing production processes can now be adapted to client requirements without rewriting from scratch.

Architectural Pattern: “ERP Core + Modules”

flowchart TD  
    A[Client Interface] --> B[API Gateway]  
    C[Internal Services (Internal ERP Platform)] --> D[Core: Data, Business Logic, Agents]  
    D --> B  
    B --> E[Module: Warehouse]  
    B --> F[Module: Production]  
    B --> G[Module: Finance]  
    D --> H[AI Agents: Forecasting, Optimization]  
    style D fill:#2d3b4e,color:#fff  
    style B fill:#4a5f75,color:#fff

Core: single source of data and business rules. Modules: independent layers connected via API. This approach enables easy system adaptation to client needs without breaking the core.

Example: How the Internal ERP Platform Processes an Order

1. The client (internal or external) sends a request via the API: POST /orders with product data, volume, and expiration date

2. API Gateway validates the token, logs the request, and forwards it to OrderProcessingAgent.

3. The agent checks resource availability, runs schedule optimization, and creates tasks for the “warehouse,” “production,” and “logistics” modules.

4. Each module returns its status to the kernel; changes are recorded in a unified database (PostgreSQL + TimescaleDB).

5. The result is returned to the client via the API, and the agent’s log is saved to a separate Kafka stream.

Pseudocode: Order API Handler

// Pseudocode: Order handler in the API layer  
POST /orders  
{  
  "client_id": "c_123",  
  "product_id": "p_456",  
  "quantity": 100,  
  "deadline": "2025-09-15T10:00:00Z"  
}  

// Inside the handler:  
const order = validateAndNormalizeOrder(req.body);  
const agent = new OrderProcessingAgent({  
  context: { client_id, product_id },  
  tools: [inventoryCheck, productionScheduler, logisticsPlanner],  
  permissions: { can_override_deadline: false }  
});  
const result = await agent.run(order);  
return { status: 'success', order_id: result.id, eta: result.eta };

Typical Mistakes in ERP “Productization”

  • Mixing configuration and code — Hardcoded rules for the current business process. Solution: Move rules to versioned configuration profiles (JSON/YAML).
  • Missing audit trail — Impossible to track who and when changed the data. Solution: Log all changes to a separate stream (Kafka + ClickHouse).
  • One API for everyone — internal and external clients use the same endpoint. Solution: split into /internal/* and /public/* with different validation rules and quotas.

Checklist: What to Verify Before Launching ERP to the External Market

  • ✅ All business rules are moved to configuration (no hardcoding)
  • ✅ Full API documentation (OpenAPI 3.0) is available
  • ✅ OAuth2 + JWT support with granular roles
  • ✅ Audit of all database changes (including soft delete)
  • ✅ Modularity: each module is a separate service/module in the code
  • ✅ Agents with fallback and Human-in-the-loop (see @codevibersen)
  • ✅ Load and Fault Tolerance Testing (Chaos Engineering)

Roles and Responsibilities in an ERP Product

flowchart LR  
    subgraph "Management"  
        CTO[CTO / Digital Director] -->|strategy| PROD[Product]  
        PROD -->|requirements| DEV  
    end  

    subgraph "Development"  
        DEV[Dev Team] -->|API| INTEG[Integrator]  
        DEV -->|config| CONFIG[Configurator]  
    end  

    subgraph "Operations"  
        CONFIG -->|profile| CLIENT[Client]  
        INTEG -->|integration| CLIENT  
        CLIENT -->|feedback| PROD  
    end  

    style DEV fill:#2d3b4e,color:#fff  
    style PROD fill:#4a5f75,color:#fff

Key principle: configuration is not developers’ responsibility. Configurators and integrators receive ready-made profiles, not code to modify. This accelerates deployment and reduces risks.