# Fiesta Backend API Reference Go + Fiber backend (`fiesta-backend/backend_fiesta`). Server listens on `:1122`. - **Base prefix:** `/live/api` - **Web group:** `/live/api/v1/web/*` — used by the merchant web app (via the `/fiesta` proxy → `https://fiesta.nearle.app`). - **Mobile group:** `/live/api/v1/mob/*` — used by the mobile app. Paths below omit the `/live/api` prefix. Query-param defaults shown in `( )`. Request-body structs are defined in [§ Models](#models) at the end. --- # GET ### Users | Path | Query params | Description | | --------------------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------- | | `/v1/web/users/getallusers` | `roleid`:int (0), `tenantid`:int (0), `pageno`:int (1), `pagesize`:int (10), `keyword`:string | List users, filterable by role/tenant | | `/v1/web/users/getusers` · `/v1/mob/users/getusers` | `userid`:int | Single user profile | ### Orders | Path | Query params | Description | | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | | `/v1/web/orders/getorders` (+ `tenant/`,`partner/`,`customer/`,`user/`,`admin/getorders`) · `/v1/mob/orders/tenant/getorders` | `tenantid`:int (0), `partnerid`:int (0), `customerid`:int (0), `moduleid`:int (0), `applocationid`:int (0), `appuserid`:int (0), `locationid`:int (0), `configid`:int (0), `status`:string, `fromdate`:string, `todate`:string, `keyword`:string, `pageno`:int (1), `pagesize`:int (10) | Orders board (role-scoped by path) | | `/v1/web/orders/getordersummary` | `tenantid`:int (0), `partnerid`:int (0), `customerid`:int (0), `locationid`:int (0), `fromdate`:string, `todate`:string | Order counts by status | | `/v1/web/orders/getlocationsummary` | `tenantid`:int | Per-location order rollup | | `/v1/web/orders/getorderinsight` | `tenantid`:int | Monthly order insight per location | | `/v1/web/orders/getorderdetails` · `/v1/mob/orders/getorderdetails` | `orderheaderid`:int | Order line items + price breakdown | | `/v1/mob/orders/getcustomerorders` | `customerid`:string, `tenantid`:string, `moduleid`:string, `fromdate`:string, `todate`:string, `orderstatus`:string, `keyword`:string, `pageno`:int (1), `pagesize`:int (10) | A customer's order history | ### Deliveries | Path | Query params | Description | | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | | `/v1/web/deliveries/getdeliveries` · `/v1/mob/deliveries/getdeliveries` | `partnerid`:int (0), `tenantid`:int (0), `userid`:int (0), `customerid`:int (0), `applocationid`:int (0), `appuserid`:int (0), `locationid`:int (0), `pageno`:int (1), `pagesize`:int, `fromdate`:string, `todate`:string, `status`:string, `keyword`:string | Deliveries board | | `/v1/web/deliveries/deliverysummary` · `/v1/mob/deliveries/deliverysummary` | `tenantid`:int (0), `partnerid`:int (0), `userid`:int (0), `applocationid`:int (0), `locationid`:int (0), `fromdate`:string, `todate`:string | Delivery counts by status | | `/v1/web/deliveries/getdeliveryinsight` | `tenantid`:int | Delivery insight per location | | `/v1/web/deliveries/getlocationsummary` | `tenantid`:int | Per-location delivery rollup | | `/v1/web/deliveries/getreportsummary` | `tenantid`:int (0), `partnerid`:int (0), `userid`:int (0), `applocationid`:int (0), `fromdate`:string, `todate`:string | Delivery report summary | | `/v1/web/deliveries/getridersummary` | `applocationid`:int (0), `partnerid`:int (0), `tenantid`:int (0), `fromdate`:string, `todate`:string | Per-rider performance summary | | `/v1/mob/deliveries/getdeliveryqueues` | `userid`:int, `fromdate`:string, `todate`:string | Rider's delivery queue | ### Products / Catalog | Path | Query params | Description | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | | `/v1/web/products/getproductcategories` | none | All product categories | | `/v1/web/products/getproductsubcategories` · `/v1/mob/...` | `categoryid`:int (0), `tenantid`:int (0) | Subcategories under a category | | `/v1/web/products/getproductscount` | `tenantid`:int, `categoryid`:int, `subcategoryid`:int, `approve`:string | Total / available / out-of-stock counts | | `/v1/web/products/getproductvariants` | `tenantid`:int, `subcategoryid`:int | Product variants | | `/v1/web/products/getcatalougeproducts` | `tenantid`:int, `locationid`:int, `subcategoryid`:int, `keyword`:string, `pageno`:int, `pagesize`:int | **Catalogue products** (curated assortment) | | `/v1/web/products/getproductstocks` | `tenantid`:string, `locationid`:string | Live stock levels | | `/v1/web/products/getstockstatement` | `tenantid`:int, `locationid`:int, `subcategoryid`:int, `pageno`:int, `pagesize`:int, `keyword`:string | Stock ledger / statement | | `/v1/web/products/getlocationproducts` · `/v1/mob/...` | `tenantid`:int, `locationid`:int, `subcategoryid`:int, `keyword`:string, `pageno`:int, `pagesize`:int | Products assigned to a location | | `/v1/web/products/getlocationproductsummary` | `tenantid`:int, `locationid`:int | Location product summary (count by subcategory) | | `/v1/web/products/getallproducts` · `/v1/mob/...` | `categoryid`:int, `subcategoryid`:int, `productid`:int, `applocationid`:int, `tenantid`:int, `locationid`:int, `keyword`:string, `productstatus`:string, `approve`:string, `pageno`:int, `pagesize`:int | All products, advanced filtering | | `/v1/mob/products/getproductbyvariant` | `tenantid`:int, `variantid`:int | Products by variant | | `/v1/mob/products/getproductsbysubcategory` | `categoryid`:int, `tenantid`:int, `applocationid`:int, `productid`:int, `keyword`:string, `locationid`:int | Products by subcategory (mobile) | ### Partners / Riders | Path | Query params | Description | | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | | `/v1/web/partners/getriders` · `/v1/mob/...` | `partnerid`:int (0), `applocationid`:int (0), `userid`:int (0), `tenantid`:int (0) | Active riders | | `/v1/web/partners/getpartners` · `/v1/mob/...` | `partnerid`:int (0), `applocationid`:int (0), `userid`:int (0) | Partners | | `/v1/web/partners/getridershifts` | `applocationid`:int (0) | Rider shifts | | `/v1/web/partners/getlocations` | `userid`:int (0), `configid`:int (0) | Location config for user | | `/v1/web/partners/getriderlogs` · `/v1/mob/...` | `partnerid`:int (0), `applocationid`:int (0), `fromdate`:string, `todate`:string *(⚠ controller reads `todate` from `fromdate` — bug)* | Rider activity logs | | `/v1/mob/partners/getriderinfo` | `userid`:int (0) | Rider profile + latest log | ### Tenants | Path | Query params | Description | | ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------- | | `/v1/web/tenants/search` | `status`:string, `keyword`:string | Search tenants | | `/v1/web/tenants/searchbykeyword` · `/v1/mob/...` | `keyword`:string | Search by keyword | | `/v1/web/tenants/getalltenants` | `pageno`:int, `pagesize`:int, `status`:string, `applocationid`:int, `tenanttype`:string, `keyword`:string | All tenants | | `/v1/web/tenants/gettenantlocations` · `/v1/mob/...` | `tenantid`:int | Tenant's outlet locations | | `/v1/mob/tenants/gettenantslot` | none | Tenant slots | | `/v1/mob/tenants/getcustomertenants` | `customerid`:int, `categoryid`:int, `tenant`:int (0=all,1=with orders) | Tenants for a customer | | `/v1/mob/tenants/gettenantpricing` | `tenantid`:int, `applocationid`:int | Tenant pricing | | `/v1/mob/tenants/getstaffs` | `tenantid`:int | Tenant staff | | `/v1/mob/tenants/gettenantinfo` | `tenantid`:int, `locationid`:int | Tenant detail | ### Customers | Path | Query params | Description | | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | --------------------------- | | `/v1/web/customers/gettenantcustomers` · `/v1/mob/...` | `tenantid`:int (0), `locationid`:int (0), `pageno`:int (0), `pagesize`:int (0), `keyword`:string | Tenant customers, paginated | | `/v1/mob/customers/getbyid` | `customerid`:int (0), `contactno`:string | Customer by id/contact | | `/v1/mob/customers/getcustomerlocation` | `customerid`:int | Customer addresses | | `/v1/mob/customers/getcustomerrequests` | `customerid`:string, `pageno`:string (1), `pagesize`:string (10) | Customer service requests | | `/v1/mob/customers/search` | `keyword`:string, `tenantid`:int (0) | Search customers | ### Utils | Path | Query params | Description | | ------------------------------------------------ | ---------------------------------------- | ----------------------------------- | | `/v1/web/utils/getapptypes` · `/v1/mob/...` | `tag`:string | App types by tag (e.g. paymentmode) | | `/v1/web/utils/getsubcategories` · `/v1/mob/...` | `moduleid`:int (0), `categoryid`:int (0) | Subcategories | | `/v1/web/utils/getapplocations` · `/v1/mob/...` | `applocationid`:int | App location detail | | `/v1/web/utils/getappcategories` · `/v1/mob/...` | none | App categories | | `/v1/mob/utils/getapplocationconfig` | `applocationid`:int | App location config | | `/v1/mob/utils/getappconfig` | `configid`:int (0) | App config | --- # POST | Path | Request body | Description | | ------------------------------------------------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------- | | `/v1/web/users/applogin` | [`User`](#user) (`authname`,`password`,`configid`,`userfcmtoken`…) | App/web login | | `/v1/web/users/create` · `/v1/mob/...` | [`User`](#user) | Create user | | `/v1/web/users/tenant/weblogin` | [`User`](#user) | Tenant web login | | `/v1/mob/users/tenant/login` | [`User`](#user) | Tenant mobile login | | `/v1/web/orders/createorder` · `/v1/mob/...` | [`Orders`](#orders) (accepts `{...}` or `{"orders":{...}}`; `tenantid` required) | Create order (+ `items[]`) | | `/v1/web/deliveries/createdeliveries` · `/v1/mob/...` | [`[]Deliveries`](#deliveries) (array) | Batch-create deliveries | | `/v1/web/products/create` | [`Products`](#products) | Create product | | `/v1/web/products/createproductstock` | [`[]Productstock`](#productstock) (array) | **Stock entry** (batch) | | `/v1/web/products/createproductlocation` | [`[]Productlocations`](#productlocations) (array) | **Assign product(s) to a store location** (price/min/max/qty) | | `/v1/web/products/createproductvariant` | [`Productvariant`](#productvariant) | Create product variant | | `/v1/web/tenants/createtenantcustomer` · `/v1/mob/...` | [`CreateTenantCustomerRequest`](#createtenantcustomerrequest) | Link customer to tenant | | `/v1/web/tenants/createlocation` · `/v1/mob/...` | [`Tenantlocations`](#tenantlocations) | Create location | | `/v1/web/tenants/createtenantlocation` | [`Tenantlocations`](#tenantlocations) | Create tenant-location | | `/v1/mob/tenants/createstaff` | [`User`](#user) | Create staff | | `/v1/mob/tenants/createtenantuser` | [`Tenants`](#tenants) (incl. nested `tenantlocations`) | Create tenant user | | `/v1/mob/customers/createlocations` | [`Customerlocations`](#customerlocations) | Create customer address | | `/v1/mob/customers/createcustomerrequest` | [`CustomerRequest`](#customerrequest) | Create customer request | | `/v1/mob/customers/login` | `{ contactno:string }` | Customer login | | `/v1/mob/customers/create` | [`Customers`](#customers) | Register customer | --- # PUT | Path | Request body | Description | | -------------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------- | | `/v1/web/users/update` · `/v1/mob/...` | [`User`](#user) | Update staff/user | | `/v1/web/orders/updateorder` · `/v1/mob/...` | [`Orders`](#orders) (`orderheaderid` required; + `items[]`) | Update order | | `/v1/web/deliveries/updatedelivery` · `/v1/mob/...` | [`UpdateDeliveryStatus`](#updatedeliverystatus) (`deliveryid` required) | Update delivery (status/rider/coords/kms) | | `/v1/web/products/update` · `/v1/mob/...` | [`Products`](#products) | Update product | | `/v1/web/products/updateproductlocation` · `/v1/mob/...` | [`Productlocations`](#productlocations) | **Update a product's location settings** (price/min/max/status) | | `/v1/web/tenants/updatelocation` · `/v1/mob/...` | [`Tenantlocations`](#tenantlocations) | Update location | | `/v1/web/tenants/updatetenantlocation` | [`Tenantlocations`](#tenantlocations) | Update tenant-location | | `/v1/mob/customers/update` | [`Customers`](#customers) | Update customer | --- # DELETE | Path | Query params | Description | | ------------------------- | --------------- | -------------- | | `/v1/web/products/delete` | `productid`:int | Delete product | --- # Models ### User | Field | Type | Notes | | :-------------- | :------- | :---- | | `userid` | `int` | | | `authname` | `string` | | | `firstname` | `string` | | | `lastname` | `string` | | | `password` | `string` | | | `email` | `string` | | | `dialcode` | `string` | | | `contactno` | `string` | | | `configid` | `int` | | | `authmode` | `int` | | | `roleid` | `int` | | | `pin` | `int` | | | `deviceid` | `string` | | | `devicetype` | `string` | | | `userfcmtoken` | `string` | | | `address` | `string` | | | `suburb` | `string` | | | `city` | `string` | | | `state` | `string` | | | `postcode` | `string` | | | `partnerid` | `int` | | | `tenantid` | `int` | | | `locationid` | `int` | | | `applocationid` | `int` | | | `status` | `string` | | | `shiftid` | `int` | | ### Orders | Field | Type | Notes | | :------------------------------------------------------------------------------------------------------ | :-------------- | :--------------------- | | `orderheaderid` | `int` | | | `tenantid` | `int` | *(required on create)* | | `locationid` | `int` | | | `applocationid` | `int` | | | `moduleid` | `int` | | | `partnerid` | `int` | | | `configid` | `int` | | | `categoryid` | `int` | | | `subcategoryid` | `int` | | | `orderid` | `string` | | | `orderdate` | `string` | | | `deliverytime` | `string` | | | `deliverytype` | `string` | | | `orderstatus` | `string` | | | `pending`/`processing`/`ready`/`delivered`/`cancelled` | `string` | | | `customerid` | `int` | | | `pickupaddress`/`pickuplat`/`pickuplong`/`pickupcustomer`/`pickupcontactno`/`pickupsuburb`/`pickupcity` | `string` | | | `deliverycustomer`/`deliverycontactno`/`deliveryaddress`/`deliverylocation`/`deliverycity` | `string` | | | `deliverylocationid` | `int` | | | `deliverylat`/`deliverylong` | `string` | | | `promotionid` | `int` | | | `promoname`/`promoterms` | `string` | | | `promovalue` | `int` | | | `promoamount`/`orderamount`/`taxamount`/`ordercharges`/`ordervalue` | `float32` | | | `itemcount` | `int` | | | `paymenttype` | `int` | | | `paymentstatus` | `int` | | | `deliverycharge` | `float32` | | | `ordernotes`/`kms`/`remarks` | `string` | | | `tenantuserid` | `int` | | | `partneruserid` | `int` | | | `smsdelivery` | `int` | | | `items` | `[]OrderDetail` | | ### Deliveries | Field | Type | Notes | | :--------------------------------------------------------------------------------------------------------------------------- | :-------- | :---- | | `deliveryid` | `int` | | | `orderheaderid` | `int` | | | `applocationid` | `int` | | | `configid` | `int` | | | `partnerid` | `int` | | | `tenantid` | `int` | | | `moduleid` | `int` | | | `locationid` | `int` | | | `categoryid` | `int` | | | `userid` | `int` | | | `subcategoryid` | `int` | | | `orderid` | `string` | | | `deliverydate` | `string` | | | `orderstatus` | `string` | | | `assigntime`/`starttime`/`arrivaltime`/`pickuptime`/`deliverytime`/`canceltime` | `string` | | | `itemcount` | `int` | | | `orderamount` | `float32` | | | `customerid` | `int` | | | `pickupcustomer`/`pickupcontactno` | `string` | | | `pickuplocationid` | `int` | | | `pickupaddress`/`pickuplocation`/`pickuplat`/`pickuplon` | `string` | | | `deliverycustomerid` | `int` | | | `deliverylocationid` | `int` | | | `deliverycustomer`/`deliverycontactno`/`deliveryaddress`/`deliverylocation`/`droplat`/`droplon`/`deliverylat`/`deliverylong` | `string` | | | `deliverycharges`/`deliveryamt` | `float32` | | | `deliverytype`/`notes`/`ordernotes`/`riderslat`/`riderslon` | `string` | | | `firstmilekm`/`firstmilecharges`/`lastmilecharges`/`ridercharges` | `float32` | | | `kms`/`actualkms` | `string` | | | `smsdelivery` | `int` | | | `paymenttype` | `int` | | ### UpdateDeliveryStatus | Field | Type | Notes | | :------------------------------------------------------------------------------ | :-------- | :----------- | | `deliveryid` | `int` | *(required)* | | `deliverytype` | `string` | | | `pickuplocationid` | `int` | | | `deliverylocationid` | `int` | | | `orderheaderid` | `int` | | | `userid` | `int` | | | `orderstatus` | `string` | | | `assigntime`/`starttime`/`arrivaltime`/`pickuptime`/`deliverytime`/`canceltime` | `string` | | | `pickuplat`/`pickuplon`/`riderslat`/`riderslon`/`deliverylat`/`deliverylong` | `string` | | | `address`/`suburb`/`city`/`state`/`postcode` | `string` | | | `deliveryamt` | `float32` | | | `kms`/`actualkms`/`riderkms`/`kmcal` | `string` | | | `notes`/`feedback` | `string` | | | `smsdelivery` | `int` | | ### Products | Field | Type | Notes | | :------------------ | :-------- | :---- | | `productid` | `int` | | | `applocationid` | `int` | | | `productlocationid` | `int` | | | `tenantid` | `int` | | | `categoryid` | `int` | | | `categoryname` | `string` | | | `subcategoryid` | `int` | | | `Subcategoryname` | `string` | | | `catalogueid` | `int` | | | `addonid` | `int` | | | `discountid` | `int` | | | `discountvalue` | `float64` | | | `pricingid` | `int` | | | `productname` | `string` | | | `productimage` | `string` | | | `productdesc` | `string` | | | `productsku` | `string` | | | `brandid` | `int` | | | `productbrand` | `string` | | | `productunit` | `string` | | | `unitvalue` | `string` | | | `toppicks` | `string` | | | `productcost` | `float64` | | | `taxamount` | `float64` | | | `taxpercent` | `float64` | | | `producttax` | `int` | | | `productstock` | `int` | | | `productcombo` | `int` | | | `variants` | `int` | | | `quantity` | `int` | | | `retailprice` | `float64` | | | `diffprice` | `float64` | | | `diffpercent` | `float64` | | | `othercost` | `float64` | | | `approve` | `int` | | | `productstatus` | `string` | | ### Productlocations | Field | Type | Notes | | :------------------ | :-------- | :------------ | | `productlocationid` | `int` | | | `tenantid` | `int` | | | `locationid` | `int` | | | `productid` | `int` | | | `catlougeid` | `int` | | | `minquantity` | `int` | (0) | | `maxquantity` | `int` | (0) | | `price` | `float32` | (0.0) | | `quantity` | `int` | *(read-only)* | | `stocktype` | `string` | *(read-only)* | | `status` | `string` | | ### Productstock | Field | Type | Notes | | :--------------- | :---------- | :---- | | `productstockid` | `int` | | | `tenantid` | `int` | | | `stockdate` | `time.Time` | | | `locationid` | `int` | | | `productid` | `int` | | | `quantity` | `int` | | | `stocktype` | `string` | | | `status` | `string` | | ### Productvariant | Field | Type | Notes | | :-------------- | :------- | :------- | | `variantid` | `int` | | | `tenantid` | `int` | | | `variantname` | `string` | | | `categoryid` | `int` | (0) | | `categoryname` | `string` | | | `subcategoryid` | `int` | | | `status` | `string` | (active) | ### Tenantlocations | Field | Type | Notes | | :--------------- | :------- | :---- | | `locationid` | `int` | | | `tenantid` | `int` | | | `applocationid` | `int` | | | `moduleid` | `int` | | | `roleid` | `int` | | | `locationname` | `string` | | | `email` | `string` | | | `contactno` | `string` | | | `latitude` | `string` | | | `longitude` | `string` | | | `address` | `string` | | | `suburb` | `string` | | | `city` | `string` | | | `state` | `string` | | | `postcode` | `string` | | | `opentime` | `string` | | | `closetime` | `string` | | | `partnerid` | `int` | | | `deliveryradius` | `int` | | | `deliverymins` | `int` | | | `cancelsecs` | `int` | | | `status` | `string` | | ### Tenants | Field | Type | Notes | | :------------------------------------------- | :---------------- | :---- | | `tenantid` | `int` | | | `tenantname` | `string` | | | `configid` | `int` | | | `partnerid` | `int` | | | `moduleid` | `int` | | | `tenanttype` | `string` | | | `registrationno` | `string` | | | `tenanttoken` | `string` | | | `companyname` | `string` | | | `devicetype` | `string` | | | `deviceid` | `string` | | | `firstname` | `string` | | | `primaryemail` | `string` | | | `primarycontact` | `string` | | | `categoryid` | `int` | | | `subcategoryid` | `int` | | | `address`/`suburb`/`city`/`state`/`postcode` | `string` | | | `latitude`/`longitude` | `string` | | | `tenantimage` | `string` | | | `tenantinfo` | `string` | | | `paymode1` | `int` | | | `paymode2` | `int` | | | `promotion` | `int` | | | `minorder` | `int` | | | `applocationid` | `int` | | | `approved` | `*int` | | | `status` | `string` | | | `partneruserid` | `int` | | | `tenantlocations` | `Tenantlocations` | | ### CreateTenantCustomerRequest | Field | Type | Notes | | :------------------- | :---- | :---- | | `moduleid` | `int` | | | `tenantid` | `int` | | | `locationid` | `int` | | | `customerid` | `int` | | | `customerlocationid` | `int` | | | `status` | `int` | | ### Customers | Field | Type | Notes | | :--------------------------------------------------------------- | :------- | :---- | | `customerid` | `int` | | | `firstname` | `string` | | | `lastname` | `string` | | | `profileimage` | `string` | | | `gender` | `string` | | | `dob` | `string` | | | `dialcode` | `string` | | | `contactno` | `string` | | | `email` | `string` | | | `deviceid` | `string` | | | `devicetype` | `string` | | | `authmode` | `int` | | | `configid` | `int` | | | `customertoken` | `string` | | | `address`/`suburb`/`city`/`state`/`landmark`/`doorno`/`postcode` | `string` | | | `latitude`/`longitude` | `string` | | | `applocationid` | `int` | | | `status` | `int` | | | `intro` | `string` | | ### Customerlocations | Field | Type | Notes | | :--------------------------------------------------------------- | :------- | :---- | | `locationid` | `int` | | | `customerid` | `int` | | | `applocationid` | `int` | | | `address`/`suburb`/`city`/`state`/`landmark`/`doorno`/`postcode` | `string` | | | `latitude`/`longitude` | `string` | | | `primaryaddress` | `int` | | | `status` | `int` | | ### CustomerRequest | Field | Type | Notes | | :------------------ | :---------- | :---- | | `customerrequestid` | `int` | | | `referencedate` | `time.Time` | | | `referencetype` | `string` | | | `customerid` | `int` | | | `tenantid` | `int` | | | `apptypeid` | `int` | | | `locationid` | `int` | | | `subject` | `string` | | | `remarks` | `string` | | | `status` | `int` | | --- *Notes:* `notifyuser` / `notifyadmin` (POST utils) exist in code but are commented out. `getriderlogs` reads `todate` from the `fromdate` query param (controller bug).