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.