Skip to content

CARGOS (Italy) Integration

Overview

CARGOS is the Italian Police system for mandatory reporting of rental contracts. Power‑Rent integrates with CARGOS to submit a fixed‑width record per contract. Submissions are initiated by users from the order UI and can be tested (Check) or sent (Send) in production mode. Both actions call the production CARGOS API; there is currently no development or staging environment for testing.

  • Available only for companies with the address in Italy.
  • When enabled, an order shows a CTA to prepare and submit to CARGOS.
  • Test mode validates the payload via the Check endpoint without persisting as sent.
  • Production mode uses the Send endpoint and marks the order as reported, storing a copy of the payload.
  • Both Check and Send call the production API; there is no dev/staging sandbox.
  • Send is disabled until a successful Check has been performed.

Credentials and Secret Management

  • Secrets source: company cargosCredentials with fields username, password (encrypted), apiKey (encrypted), and offices mapping.
  • Encryption key: Vercel Edge Config item cargosCredentialsKey.
    • Used to encrypt on write and decrypt on read.
    • Missing key raises an error in resolvers.
  • Reading credentials masks secret values in GraphQL to avoid leaking secrets.
  • Office mapping associates internal offices to CARGOS AGENZIA fields.

References:

  • Edge config access in resolvers: get('cargosCredentialsKey').
  • Encryption helper: lib/cargos/encryptCargosCredentials.js.
  • Resolver masking: server/graphql/resolvers/query/cargosCredentials.resolver.js.

Data Model (Prisma)

  • cargos_reports: stored copy of the last submitted report per order (mirrors CARGOS fields like CONTRATTO_ID, dates, AGENZIA info, etc.).
  • cargos_states: lookup table for places (communes) and codes.
  • cargos_citizenship: lookup table for citizenship codes.

Persistence behavior:

  • On successful production submission (Send), the order is marked and a row is inserted in cargos_reports.
  • Idempotency: repeat Send attempts for the same CONTRATTO_ID should not duplicate business state.

Server API

Schema:

  • File: server/graphql/schema/cargos.graphql
  • Types: CargosReport, CargosData
  • Input: CargosReportInput
  • Mutation: submitCargos(input: CargosReportInput!, test: Boolean!): CargosResponse!

Resolvers:

  • Mutation: server/graphql/resolvers/mutation/submitCargos.resolver.js
    • Builds fixed‑width payload, sets headers, calls Check/Send, persists when test=false.
  • Lookups (examples):
    • cargosStates, cargosCitizenshipCodes, cargosVehicleTypes, cargosDocumentTypes, cargosPaymentTypes under server/graphql/resolvers/query/*.

Services and Dataloaders:

  • services/global/CargosService.ts: Prisma‑backed helpers for cargos_reports, states, and citizenship.
  • Dataloader caches the CARGOS token and credentials lookups.

Feature Flags influence:

  • faunaMigrationTenantCompanies, faunaMigrationOrders toggle FaunaDB vs Postgres code paths.
  • When Postgres is enabled, CargosService provides the lookups and persistence.

Endpoints and network:

  • Base: https://cargos.poliziadistato.it/CARGOS_API/api
  • Test: .../Check
  • Production: .../Send
  • Both endpoints are production-only; no sandbox/staging API is available.

Frontend

  • Settings toggle card: components/pages/Settings/Integrations/CargosIntegration.js (enables the feature).
  • Office mapping form: components/pages/Settings/CompaniesOffices/OfficeModal/CargosIntegration.js ( fills AGENZIA fields, uses CargosStateSelector).
  • Order CTA: components/pages/Cargos/CargosButton checks prerequisites (drivers, credentials) and routes to the flow.
  • Flow pages:
    • pages/cargos/[addCargosNumber].js — prepare and test/send.
    • pages/cargos/view/[viewCargosNumber].js — view sent report.
  • Select inputs fetch options from GraphQL viewer.cargosData.* (states, citizenship, vehicle/document/payment types).

Submission Flow

  1. Token acquisition
  • Build username:password, obtain access token from CARGOS via dataloader.
  • Encrypt token with company apiKey before making API calls.
  1. Payload formatting
  • Fields are fixed‑width; formatters pad and trim values per spec.
  • Timezone‑aware date formatting for dd/MM/yyyy HH:mm fields.
  1. API call
  • Test mode: POST to Check with a single fixed‑width record in body.
  • Production mode: POST to Send, then update order state and persist cargos_reports.
  • UI gating: the Send action remains disabled until Check passes.
  1. Error handling
  • API errors returned as CargosResponse { success, message }.
  • Sentry captures failures with codes.cargosApiError where relevant.

Ops / Requirements

  • Vercel Edge Config: must include cargosCredentialsKey.
  • Outbound HTTPS to CARGOS. A custom https.Agent with legacy TLS options may be required.
  • Observability: Sentry is integrated in resolvers and services; GraphQL surfaces errors to the UI.
  • Feature flags: ensure Postgres/Fauna flags are in the desired state for your environment.

How to Use / Test

UI flow (recommended):

  • Enable integration in Settings > Integrations.
  • Map offices to CARGOS AGENZIA fields in Companies/Offices.
  • Open an order with a driver, click the CARGOS button.
  • Use Test (Check) first; when it succeeds, the Send button becomes enabled to finalize.

GraphQL example (test mode):

mutation TestCargos($input: CargosReportInput!) {
submitCargos(input: $input, test: true) {
success
message
}
}

Common issues:

  • Missing credentials or drivers: UI will show localized messages (see lang/* for CargosButton.*).
  • Edge config key missing: server returns error mentioning cargosCredentialsKey.
  • Place or citizenship code not found: ensure selectors use exact search or update lookup tables.

File Index (quick reference)

  • GraphQL schema: server/graphql/schema/cargos.graphql
  • Mutation resolver: server/graphql/resolvers/mutation/submitCargos.resolver.js
  • Lookups: server/graphql/resolvers/query/* (cargos*)
  • Service: services/global/CargosService.ts
  • Order persistence: services/tenant/OrderService/OrderService.ts#addCargosReport
  • Encryption: lib/cargos/encryptCargosCredentials.js
  • UI: components/pages/Cargos/*, pages/cargos/*, components/pages/Settings/Integrations/CargosIntegration.js
  • Lookups UI: selectors under components/pages/Cargos/*Selector*