APIs & services / portfolio-service

Create a compact block (group of adjacent lands).

Endpointtoday's app
Call
POST /gateway/portfolio-service/api/v1/compact-block
Service
portfolio-service
Features
Compact Block
When
Queued sync (COMPACT_BLOCK POST)
Auth
X-SESSIONID stamped when queued (CoreAPI dooWithRetry); X-REQUESTID idempotency key
In the App Service

Use case

Queued create of a compact block (COMPACT_BLOCK POST via CompactBlockWorker) after the user groups adjacent lands on the compact block screen. CompactBlockPostRH saves the server block id and member ids (by uuid) and marks them synced. Failures retry.

Headers

HeaderValueNotes
X-SESSIONID<session token>Stamped when the operation is queued (dooWithRetry) and re-set by CoreAPI at send time; refreshed on 401.
X-REQUESTID<uuid v4>Idempotency key generated by OperationManagerImpl.createOperation for POST/PUT/PATCH when the op enters the offline queue.
X-ACK-REQUESTID<X-REQUESTID of an earlier completed op>Added by SyncQueueProcessor for POST/PUT/PATCH: acknowledges a request id the device already saw succeed.
Content-Typeapplication/jsonAdded by CoreAPI.

Request

Example request body (synthetic data)
{
  "id": null,
  "name": "Compact Block A",
  "compactBlockCreatedAt": "2026-07-01",
  "compactBlockLastUpdateAt": "2026-07-01",
  "titleId": "CB-TITLE-0001",
  "note": "Adjacent paddy lands",
  "active": true,
  "inActiveReason": null,
  "createdByApp": 109,
  "lastModifiedByApp": 109,
  "createdFromDevice": "<device id>",
  "lastUpdatedFromDevice": "<device id>",
  "compactBlockMembers": [
    {
      "assetCheckSum": "<asset checksum>",
      "assetCode": "ASSET-CODE-0001",
      "assetId": 9001,
      "id": 0,
      "joiningDate": "2026-07-01",
      "leavingDate": null,
      "titleId": "CB-TITLE-0001",
      "notes": null,
      "owningEntityId": "40001",
      "owningEntityType": "ENTITY_TYPE.IE",
      "active": true,
      "inActiveReason": null,
      "shgId": "SHG-ALIAS-01",
      "vo": "VO-ALIAS-01",
      "uuid": "cbm-0000-4000-8000-000000000701",
      "portfolioLineItemTitleId": "TILE-0001",
      "portfolioLineItemId": 6001,
      "portfolioId": 5001,
      "createdByApp": 109,
      "lastModifiedByApp": 109,
      "createdFromDevice": "<device id>",
      "lastUpdatedFromDevice": "<device id>",
      "appId": "cbm-0000-4000-8000-000000000701",
      "syncStatus": "SYNC_PENDING"
    }
  ],
  "appId": "cb-0000-4000-8000-000000000601",
  "syncStatus": "SYNC_PENDING"
}
FieldTypeRequiredNotes
idlongNoServer id (null on create; filled from DB for PUT).
name / note / titleIdstringYesCompact block form; titleId is unique (compact_block.titleId).
compactBlockCreatedAt / compactBlockLastUpdateAtstringNoDates set by the app.
active / inActiveReasonboolean / stringNoDeactivation reason when removed.
createdByApp, lastModifiedByApp, createdFromDevice, lastUpdatedFromDevicelong / stringNoAudit fields.
compactBlockMembers[]arrayYesLands in the block: assetCode/assetId/assetCheckSum, owningEntityId (farmer IE id), shgId, vo, uuid, portfolioLineItemId/TitleId/portfolioId (crop on that land), joiningDate, active.
appId, opId, syncStatusstringNoLocal columns serialised by Moshi/Gson; ignored by server.

Response

Example response body (synthetic data)
{
  "id": 6101,
  "name": "Compact Block A",
  "compactBlockCreatedAt": "2026-07-01",
  "compactBlockLastUpdateAt": "2026-07-01",
  "titleId": "CB-TITLE-0001",
  "note": "Adjacent paddy lands",
  "active": true,
  "inActiveReason": null,
  "createdByApp": 109,
  "lastModifiedByApp": 109,
  "createdFromDevice": "<device id>",
  "lastUpdatedFromDevice": "<device id>",
  "compactBlockMembers": [
    {
      "assetCheckSum": "<asset checksum>",
      "assetCode": "ASSET-CODE-0001",
      "assetId": 9001,
      "id": 6201,
      "joiningDate": "2026-07-01",
      "leavingDate": null,
      "titleId": "CB-TITLE-0001",
      "notes": null,
      "owningEntityId": "40001",
      "owningEntityType": "ENTITY_TYPE.IE",
      "active": true,
      "inActiveReason": null,
      "shgId": "SHG-ALIAS-01",
      "vo": "VO-ALIAS-01",
      "uuid": "cbm-0000-4000-8000-000000000701",
      "portfolioLineItemTitleId": "TILE-0001",
      "portfolioLineItemId": 6001,
      "portfolioId": 5001,
      "createdByApp": 109,
      "lastModifiedByApp": 109,
      "createdFromDevice": "<device id>",
      "lastUpdatedFromDevice": "<device id>"
    }
  ]
}
FieldTypeRequiredNotes
idlongcompact_block.id.
compactBlockMembers[].id / uuidmixedcompact_block_member.id by uuid.

Errors

StatusWhenWhat the app does
401Session token expired or invalidCoreAPI invalidates the session id and retries once immediately; if still failing the op stays in the queue (TryAgain.LATER).
500Server error on a /gateway URLBaseResponseHandler fetches a new session id (first 5 attempts) and returns TryAgain.LATER; retried per RetryScheduler policy (retry threshold/delay come from app config).
503Service unavailableCoreAPI retries once immediately, then the op is retried later by the sync queue.
any non-2xxAny other failureHandler onError -> TryAgain.LATER (op stays queued and is visible in Pending Sync); a row is written to the local error_log table (Sync Error Log screen) with URL, body, headers and raw response; every 10th attempt the op is mirrored to Firestore for support.

Source

  • data/src/main/java/org/mindtree/app/agricultor/data/entity/CompactBlock.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/sync/work/CompactBlockWorker.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/sync/rh/CompactBlockPostRH.kt
  • app/src/main/java/org/platformcommons/urvi/bridge/BridgeSyncHelper.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/manager/CoreAPIManager.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/sync/rh/BaseResponseHandler.kt
  • offline-core/src/main/java/com/mindtree/bridge/coreapi/offline/SyncQueueProcessor.java
  • offline-core/src/main/java/com/mindtree/bridge/coreapi/offline/manager/OperationManagerImpl.java
  • core-api/src/main/java/com/mindtree/bridge/coreapi/impl/CoreAPIDefaultImpl.java