Skip to main content

Dimension combinations

Overview

The Dimension Combinations API provides intelligent dimension resolution and validation services for financial transaction entry. This API supports the interactive workflow where users progressively build complete dimensional account combinations with real-time validation and intelligent suggestions.

Base URL: /general-ledger/dimension-combinations

Key Features

  • Intelligent Account Structure Resolution: Automatically determines the correct account structure based on MainAccount value
  • Interactive Validation: Real-time validation of dimension values without creating permanent records
  • Smart Suggestions: Context-aware suggestions for partial entries and alternatives
  • Progressive Entry Support: Handles incomplete dimension combinations during user input
  • Multi-Ledger Support: Works with multiple ledger configurations
  • Performance Optimized: Lightweight validation for responsive UI experiences

Core Endpoint

Resolve and Suggest Segments

The primary endpoint for interactive dimension resolution and validation.

POST /general-ledger/dimension-combinations/resolve-and-suggest-segments
Content-Type: application/json

Purpose

This endpoint serves three critical functions:

  1. Account Structure Resolution: Determines which account structure applies based on MainAccount
  2. UI Metadata: Returns required dimension fields for dynamic UI rendering
  3. Interactive Validation: Validates entered values and provides intelligent suggestions

Request Body

{
"ledger_id": "12345678-1234-1234-1234-123456789012",
"request_context": "journal_entry",
"segment_inputs": [
{
"dimension_attribute_id": "00000000-0000-0000-0000-000000000001",
"value": "1100"
},
{
"dimension_attribute_id": "b2c3d4e5-f6a7-8901-2345-678901bcdef0",
"value": "SALES"
}
]
}

Request Fields:

  • ledger_id (required): The ledger context for dimension resolution
  • request_context (optional): Context hint for logging and analytics
  • segment_inputs (required): Array of dimension values entered by the user
    • dimension_attribute_id: The specific dimension attribute being set
    • value: The string value entered by the user

Success Response (200 OK)

{
"account_structure_id": "a1b2c3d4-e5f6-a1b2-c3d4-e5f6a1b2c3d4",
"account_structure_name": "Assets Account Structure",
"account_structure_description": "Standard structure for all Asset accounts",
"required_levels": [
{
"level": 1,
"dimension_attribute_id": "00000000-0000-0000-0000-000000000001",
"dimension_attribute_name": "MainAccount",
"is_mandatory": true
},
{
"level": 2,
"dimension_attribute_id": "b2c3d4e5-f6a7-8901-2345-678901bcdef0",
"dimension_attribute_name": "Department",
"is_mandatory": true
},
{
"level": 3,
"dimension_attribute_id": "5a8e9e4e-0b0c-4c4c-8b8b-0a0a0a0a0a0a",
"dimension_attribute_name": "CostCenter",
"is_mandatory": false
}
],
"validation_results": [
{
"dimension_attribute_id": "00000000-0000-0000-0000-000000000001",
"value": "1100",
"is_valid": true,
"message": "Valid value",
"resolved_value_id": "d7f6e5a7-c2b3-4d09-7a5e-1b6c3d7f4e9a",
"suggested_values": []
},
{
"dimension_attribute_id": "b2c3d4e5-f6a7-8901-2345-678901bcdef0",
"value": "SALES",
"is_valid": true,
"message": "Valid value",
"resolved_value_id": "c3d4e5f6-a7b8-9012-3456-789012cdef01",
"suggested_values": ["SALES", "MARKETING", "SUPPORT", "IT"]
}
],
"has_warnings": false,
"warnings": []
}

Response Fields:

Account Structure Information:

  • account_structure_id: The resolved account structure (dimension hierarchy) ID
  • account_structure_name: Display name of the account structure
  • account_structure_description: Optional description of the account structure

Required Levels (for UI Rendering):

  • required_levels: Array of dimension fields the UI should render
    • level: The order/position of this dimension in the structure
    • dimension_attribute_id: Unique identifier for the dimension attribute
    • dimension_attribute_name: Display name (e.g., "MainAccount", "Department")
    • is_mandatory: Whether this dimension is required for valid combinations

Validation Results:

  • validation_results: Validation status for each provided segment input
    • dimension_attribute_id: The dimension attribute that was validated
    • value: The exact value that was validated
    • is_valid: Whether the value exists and is active
    • message: Human-readable validation result
    • resolved_value_id: Internal ID of the dimension value (if valid)
    • suggested_values: Intelligent suggestions (see Suggestion Logic below)

Warnings:

  • has_warnings: Whether any warnings were generated during resolution
  • warnings: Array of warning messages (e.g., ambiguous account structure)

Intelligent Suggestion Logic

1. Partial Match Assistance 🎯

Scenario: User enters incomplete values Behavior: Suggest completions for what they're typing

// User types: "SA"
{
"dimension_attribute_id": "dept-id",
"value": "SA",
"is_valid": false,
"suggested_values": ["SALES", "SUPPORT", "SAFETY"]
}

2. Alternative Options 💡

Scenario: User enters valid value for commonly-changed dimensions Behavior: Show related alternatives they might want instead

// User enters valid "SALES"
{
"dimension_attribute_id": "dept-id",
"value": "SALES",
"is_valid": true,
"suggested_values": ["SALES", "MARKETING", "SUPPORT", "IT"]
}

3. Clean UI for Complete Values ✅

Scenario: User enters definitive, complete values Behavior: No redundant suggestions

// User enters complete MainAccount
{
"dimension_attribute_id": "main-account-id",
"value": "1100",
"is_valid": true,
"suggested_values": [] // Clean - no clutter
}

Usage Patterns

Pattern 1: Initial MainAccount Entry

When user first enters a MainAccount value:

// User enters MainAccount "1100"
const response = await fetch('/general-ledger/dimension-combinations/resolve-and-suggest-segments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ledger_id: currentLedgerId,
segment_inputs: [
{
dimension_attribute_id: mainAccountDimensionId,
value: "1100"
}
]
})
});

const result = await response.json();

// Use result.required_levels to render additional input fields
result.required_levels.forEach(level => {
if (level.level > 1) { // Skip MainAccount (level 1)
renderDimensionInput(level);
}
});

Pattern 2: Progressive Validation

As user fills additional dimensions:

// User has entered MainAccount + Department
const response = await fetch('/general-ledger/dimension-combinations/resolve-and-suggest-segments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ledger_id: currentLedgerId,
segment_inputs: [
{
dimension_attribute_id: mainAccountDimensionId,
value: "1100"
},
{
dimension_attribute_id: departmentDimensionId,
value: "SALES"
}
]
})
});

// Use validation_results to show real-time feedback
const result = await response.json();
result.validation_results.forEach(validation => {
updateFieldValidation(validation.dimension_attribute_id, validation);
});

Pattern 3: Type-ahead Support

For responsive type-ahead suggestions:

// User types partial value
const handleInputChange = async (dimensionAttributeId, partialValue) => {
if (partialValue.length >= 2) { // Avoid too many requests
const response = await fetch('/general-ledger/dimension-combinations/resolve-and-suggest-segments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ledger_id: currentLedgerId,
segment_inputs: [
{ dimension_attribute_id: mainAccountDimensionId, value: currentMainAccount },
{ dimension_attribute_id: dimensionAttributeId, value: partialValue }
]
})
});

const result = await response.json();
const suggestions = result.validation_results
.find(v => v.dimension_attribute_id === dimensionAttributeId)
?.suggested_values || [];

showSuggestions(dimensionAttributeId, suggestions);
}
};

Error Scenarios

Account Structure Not Resolvable (500 Internal Server Error)

When the MainAccount value doesn't match any active account structure:

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Internal Server Error",
"status": 500,
"detail": "Could not resolve account structure for MainAccount value '9999': No matching account structure found for this MainAccount in the specified ledger."
}

Invalid Request Data (400 Bad Request)

When required fields are missing or invalid:

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"LedgerId": ["The LedgerId field is required."],
"SegmentInputs": ["At least one segment input is required."]
}
}

Ledger Not Found (404 Not Found)

When the specified ledger doesn't exist:

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
"title": "Not Found",
"status": 404,
"detail": "Ledger with ID '12345678-1234-1234-1234-123456789012' not found."
}

Integration with Journal Entry

Complete Workflow

class DimensionEntryComponent {
async handleMainAccountEntry(mainAccountValue) {
// Step 1: Resolve account structure and get required fields
const resolution = await this.resolveAndSuggestSegments([
{ dimension_attribute_id: this.mainAccountDimId, value: mainAccountValue }
]);

// Step 2: Render required dimension fields
this.renderRequiredFields(resolution.required_levels);

// Step 3: Show validation feedback
this.updateValidation(resolution.validation_results);
}

async handleDimensionValueChange(dimensionAttributeId, value) {
// Get current values for all dimensions
const allSegments = this.getCurrentSegmentValues();

// Update the changed value
const updatedSegments = allSegments.map(segment =>
segment.dimension_attribute_id === dimensionAttributeId
? { ...segment, value }
: segment
);

// Validate and get suggestions
const resolution = await this.resolveAndSuggestSegments(updatedSegments);
this.updateValidation(resolution.validation_results);
}

async saveJournalTransaction() {
// Validate all dimensions are complete
const allSegments = this.getCurrentSegmentValues();
const resolution = await this.resolveAndSuggestSegments(allSegments);

if (resolution.validation_results.every(v => v.is_valid)) {
// All valid - proceed with journal creation
const journal = await this.createJournal({
transactions: [{
dimension_segments: allSegments,
// ... other transaction data
}]
});
} else {
// Show validation errors
this.showValidationErrors(resolution.validation_results);
}
}

async resolveAndSuggestSegments(segments) {
const response = await fetch('/general-ledger/dimension-combinations/resolve-and-suggest-segments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ledger_id: this.currentLedgerId,
request_context: 'journal_entry',
segment_inputs: segments
})
});

if (!response.ok) {
throw new Error(`Dimension resolution failed: ${response.status}`);
}

return await response.json();
}
}

Performance Considerations

Caching Strategy

  • Account Structure Resolution: Cache resolved structures by MainAccount pattern
  • Dimension Metadata: Cache dimension attribute information client-side
  • Validation Results: Cache validation results for repeated values

Request Optimization

  • Debounce Input: Avoid excessive requests during rapid typing
  • Batch Validation: Validate multiple segments in single request
  • Progressive Enhancement: Start with required fields, expand as needed

Response Size Management

  • Suggestion Limits: Maximum 5 suggestions per field
  • Required Levels Only: Only return levels needed for current account structure
  • Minimal Metadata: Include only essential information for UI rendering

Testing Scenarios

Test Case 1: Asset Account Structure Resolution

POST /general-ledger/dimension-combinations/resolve-and-suggest-segments
{
"ledger_id": "test-ledger-id",
"segment_inputs": [
{ "dimension_attribute_id": "main-account-dim-id", "value": "1100" }
]
}

# Expected: Account structure for assets (MainAccount + Department + CostCenter)

Test Case 2: Revenue Account Structure Resolution

POST /general-ledger/dimension-combinations/resolve-and-suggest-segments
{
"ledger_id": "test-ledger-id",
"segment_inputs": [
{ "dimension_attribute_id": "main-account-dim-id", "value": "4100" }
]
}

# Expected: Account structure for revenue (MainAccount + Customer + Project)

Test Case 3: Partial Department Entry

POST /general-ledger/dimension-combinations/resolve-and-suggest-segments
{
"ledger_id": "test-ledger-id",
"segment_inputs": [
{ "dimension_attribute_id": "main-account-dim-id", "value": "1100" },
{ "dimension_attribute_id": "department-dim-id", "value": "SA" }
]
}

# Expected: Suggestions like ["SALES", "SUPPORT", "SAFETY"]

Test Case 4: Invalid MainAccount

POST /general-ledger/dimension-combinations/resolve-and-suggest-segments
{
"ledger_id": "test-ledger-id",
"segment_inputs": [
{ "dimension_attribute_id": "main-account-dim-id", "value": "9999" }
]
}

# Expected: 500 Internal Server Error - no matching account structure