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
Checkendpoint without persisting as sent. - Production mode uses the
Sendendpoint 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
cargosCredentialswith fieldsusername,password(encrypted),apiKey(encrypted), andofficesmapping. - 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 likeCONTRATTO_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 incargos_reports. - Idempotency: repeat
Sendattempts for the sameCONTRATTO_IDshould 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 whentest=false.
- Builds fixed‑width payload, sets headers, calls
- Lookups (examples):
cargosStates,cargosCitizenshipCodes,cargosVehicleTypes,cargosDocumentTypes,cargosPaymentTypesunderserver/graphql/resolvers/query/*.
Services and Dataloaders:
services/global/CargosService.ts: Prisma‑backed helpers forcargos_reports, states, and citizenship.- Dataloader caches the CARGOS token and credentials lookups.
Feature Flags influence:
faunaMigrationTenantCompanies,faunaMigrationOrderstoggle FaunaDB vs Postgres code paths.- When Postgres is enabled,
CargosServiceprovides 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, usesCargosStateSelector). - Order CTA:
components/pages/Cargos/CargosButtonchecks 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
- Token acquisition
- Build
username:password, obtain access token from CARGOS via dataloader. - Encrypt token with company
apiKeybefore making API calls.
- Payload formatting
- Fields are fixed‑width; formatters pad and trim values per spec.
- Timezone‑aware date formatting for
dd/MM/yyyy HH:mmfields.
- API call
- Test mode: POST to
Checkwith a single fixed‑width record in body. - Production mode: POST to
Send, then update order state and persistcargos_reports. - UI gating: the Send action remains disabled until Check passes.
- Error handling
- API errors returned as
CargosResponse { success, message }. - Sentry captures failures with
codes.cargosApiErrorwhere 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/*forCargosButton.*). - 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*