================================================================================

 BrightProductsController - Summary & Response Structures

 File: SonWinCommonAPI/Controllers/BrightProductsController.cs

================================================================================


--------------------------------------------------------------------------------

 WHAT THE CONTROLLER DOES

--------------------------------------------------------------------------------

Exposes a single read endpoint that returns the price products / tariffs tied to

one customer + one service (metering point / EAN number) within a date range.

The data is read from the SonWin (Sonlinc) contract tables;

The query selects the contract "lines" for the requested EAN number.

--------------------------------------------------------------------------------

 METHODS

--------------------------------------------------------------------------------

1) GetProducts

   Route:    GET bright/products

   Auth:     [Authorize] (controller-level)

   Params:  

  • customerId (query)
  • serviceId (query)
  • DateFrom (query DateTime)
  • DateTo (query DateTime)
  • CancellationToken ct

   Body:     none

   Returns: 

  • 200 OK -> IEnumerable<BrightProduct>
  • 400 BadRequest (declared, never produced - see NOTE)
  • 401 Unauthorized (from auth middleware, not the action)

   What it does:

  • Validates the customer
  • validates the inputs
  • queries active contracts for the customer + EAN within the date range
  • validates that every returned row belongs to the requested serviceId
  • Groups by AftageNr
  • Maps each group to a BrightProduct with a list of BrightPrice lines.

   Validation that affects the result (ALL failures surface as HTTP 500:

     Customer validation (AccountValidator.ValidateAccountGetOutput):

  •        no customer row              -> "No customer found with Id '<id>'."
  •        more than one row            -> "Unique active customer could not be identified. Id: '<id>'."
  •        row has empty CustomerId     -> "The customer returned did not have any CustomerId."
  •        returned id != requested     -> "Returned customer '<x>' does not match requested '<id>'."

     Input validation (ProductsValidator.ValidateGetProductsAsyncInput):       

  • customerId blank             -> "Missing parameter 'CustomerId'."
  •        serviceId blank              -> "Missing parameter 'ServiceId'."
  •        serviceId non-digit          -> "Parameter 'ServiceId' must contain digits only."
  •        DateFrom == default          -> "Missing parameter 'DateFrom'."
  •        DateTo == default            -> "Missing parameter 'DateTo'."
  •        DateFrom >= DateTo           -> "'DateFrom' must be before 'DateTo'."

Output validation (ProductsValidator.ValidateGetProductsAsyncOutput):

  • Any row.AftageNr != serviceId -> "Products belong to wrong ServiceId(s):
  • <ids>. Expected ServiceId: <id>.
  • CustomerId <id>, daterange: <from>-<to>"

--------------------------------------------------------------------------------

 RESPONSE STRUCTURE (IEnumerable<BrightProduct>)

--------------------------------------------------------------------------------

Top level is a JSON array of BrightProduct. One element per distinct AftageNr

(EAN). Because the query filters on a single @EanNumber, in practice there is

one group, and each contract row becomes one entry in that group's Prices list.

[
  {
    "ValidFrom": null,             // Hardcoded null 
    "ValidTo": null,               // Hardcoded null 
    "ServiceId": "<serviceId>",    // Echo of request serviceId param (MeteringPointId)
    "Prices": [
      {
        "Value": 0,                // Hardcoded 0 
        "Type": "kWh",             // Hardcoded "kWh" 
        "Note": null,              // Hardcoded null 
        "Name": "kWhPrice",        // Hardcoded "kWhPrice" 
        "ValidFrom": "<datetime>", // Data: AFORBKONTR.FRADATO (DbProduct.ContractActiveFrom)
        "ValidTo": "<datetime>",   // Data: AFORBKONTR.TILDATO (DbProduct.ContractActiveTo); null = open-ended
        "ValidHours": [],          // Not mapped 
        "ValidMonth": [],          // Not mapped 
        "ValidPart": null,         // Not mapped 
        "ValidFraction": null,     // Not mapped 
        "SubtractMeasurement": null// Not mapped 
      }
    ]
  }
]


  • No labels