{"schemaVersion":"mappls.contract-generations.v1","boundary":"Preferred means the highest version-labelled generation retained in this source snapshot. It does not establish current provider support, compatibility, entitlement, regional availability, or a safe production migration.","group":{"slug":"mgis-get-describedataset-855417da71","family":"mgis","familyName":"mGIS Analytics","product":"mGIS","stateModel":"stateful","method":"GET","path":"/describeDataset","title":"GET /describeDataset","preferredGeneration":"v2","preferredSlug":"mgis-get-describedataset-fetches-the-attribute-names","variants":[{"generation":"v1","apiVersion":"V1.0.0","slug":"mgis-get-describedataset-fetches-the-attribute-names-v1","href":"/api-reference/mgis-get-describedataset-fetches-the-attribute-names-v1","summary":"fetches the attribute names.","sourceFile":"mappls-developer-platform/data/corpus/public-api-contracts/mapmyindia-mgis-apis/docs/v1/custom/describe-dataset-api.yml","sourceFingerprint":"c981431acc37f36caebfd2b0f9c66ad08ebedef3f93e0eba70375b935d27fadd","baseUrl":"https://mgis-api.mappls.com/","authMode":"bearer","parameterKeys":["query:datasetNme"],"requiredParameterKeys":["query:datasetNme"],"requestFields":[],"requiredRequestFields":[],"responseStatuses":["200","400","401","404","422","500"],"responseFields":["200:code","200:propertyList","200:propertyList[].ColumnName","200:propertyList[].ColumnType","400:auth","400:code","400:error","400:message","401:code","401:error","404:code","404:error","422:code","422:error","500:code","500:error"],"isPreferredGeneration":false},{"generation":"v2","apiVersion":"V2.0.0","slug":"mgis-get-describedataset-fetches-the-attribute-names","href":"/api-reference/mgis-get-describedataset-fetches-the-attribute-names","summary":"fetches the attribute names.","sourceFile":"mappls-developer-platform/data/corpus/public-api-contracts/mapmyindia-mgis-apis/docs/v2/custom/describe-dataset-api.yml","sourceFingerprint":"ea4acadc9a13ed87bdc8f5b4a009cb6eebcc13efc93221a3103ac8f5ea70c9b6","baseUrl":"https://mgis-apiv2.mappls.com/","authMode":"bearer","parameterKeys":["query:dataStoreName","query:datasetNme"],"requiredParameterKeys":["query:datasetNme"],"requestFields":[],"requiredRequestFields":[],"responseStatuses":["200","400","401","500"],"responseFields":["200:code","200:data","200:data.propertyList","200:data.propertyList[].ColumnName","200:data.propertyList[].ColumnType","200:message","200:success","400:code","400:message","401:code","401:message","500:code","500:message"],"isPreferredGeneration":true}],"transitions":[{"fromGeneration":"v1","fromSlug":"mgis-get-describedataset-fetches-the-attribute-names-v1","toGeneration":"v2","toSlug":"mgis-get-describedataset-fetches-the-attribute-names","addedParameters":["query:dataStoreName"],"removedParameters":[],"newlyRequiredParameters":[],"addedRequestFields":[],"removedRequestFields":[],"newlyRequiredRequestFields":[],"addedResponseStatuses":[],"removedResponseStatuses":["404","422"],"addedResponseFields":["200:data","200:data.propertyList","200:data.propertyList[].ColumnName","200:data.propertyList[].ColumnType","200:message","200:success","401:message","500:message"],"removedResponseFields":["200:propertyList","200:propertyList[].ColumnName","200:propertyList[].ColumnType","400:auth","400:error","401:error","404:code","404:error","422:code","422:error","500:error"],"authChanged":false,"baseUrlChanged":true,"breakingSignals":["Response status no longer declared: 404","Response status no longer declared: 422","Declared server URL changed"],"migrationChecklist":["Confirm the Mappls account is entitled to v2; source ordering is not availability proof.","Run both retained contract generations against sanitized fixtures and compare application parsing.","Update only declared parameters and request fields; do not infer undocumented aliases.","Exercise authentication rejection, validation, rate-limit, timeout, and unknown-outcome handling.","For state-changing operations, migrate behind an idempotent adapter and reconcile before retry.","Retain the source fingerprints, acceptance evidence, rollback trigger, and previous adapter until approval."]}],"evidenceBoundary":"Preferred means the highest version-labelled generation retained in this source snapshot. It does not establish current provider support, compatibility, entitlement, regional availability, or a safe production migration."},"migrationKit":{"schemaVersion":"mappls.contract-generation-migration-kit.v1","slug":"mgis-get-describedataset-855417da71-migration-kit","groupSlug":"mgis-get-describedataset-855417da71","title":"GET /describeDataset: v1 → v2","fromGeneration":"v1","toGeneration":"v2","downloadPath":"/downloads/api-generations/mgis-get-describedataset-855417da71-migration-kit.zip","checksumPath":"/downloads/api-generations/mgis-get-describedataset-855417da71-migration-kit.zip.sha256","adapterLanguages":["JavaScript","Python","Java","C#","Go","PHP","Ruby","Kotlin"],"verifiedTests":3,"providerCalls":0,"credentialsAccepted":false,"files":[{"path":"README.md","language":"markdown","purpose":"Migration workshop and runbook"},{"path":"MIGRATION_MANIFEST.json","language":"json","purpose":"Exact machine-readable source and diff identity"},{"path":"ACCEPTANCE.md","language":"markdown","purpose":"Success and hostile-path evidence"},{"path":"ROLLBACK.md","language":"markdown","purpose":"Generation-safe cutover and rollback plan"},{"path":"fixtures/source-envelope.json","language":"json","purpose":"Sanitized source-generation shape"},{"path":"fixtures/target-envelope.json","language":"json","purpose":"Sanitized target-generation shape"},{"path":"src/runtime/adapter.mjs","language":"javascript","purpose":"Executable allow-list adapter"},{"path":"src/runtime/inspect.mjs","language":"javascript","purpose":"Offline fixture inspector"},{"path":"src/adapters/adapter.mjs","language":"javascript","purpose":"JavaScript application-owned adapter scaffold"},{"path":"src/adapters/adapter.py","language":"python","purpose":"Python application-owned adapter scaffold"},{"path":"src/adapters/MapplsGenerationAdapter.java","language":"java","purpose":"Java application-owned adapter scaffold"},{"path":"src/adapters/MapplsGenerationAdapter.cs","language":"csharp","purpose":"C# application-owned adapter scaffold"},{"path":"src/adapters/adapter.go","language":"go","purpose":"Go application-owned adapter scaffold"},{"path":"src/adapters/adapter.php","language":"php","purpose":"PHP application-owned adapter scaffold"},{"path":"src/adapters/adapter.rb","language":"ruby","purpose":"Ruby application-owned adapter scaffold"},{"path":"src/adapters/MapplsGenerationAdapter.kt","language":"kotlin","purpose":"Kotlin application-owned adapter scaffold"},{"path":"test/adapter.test.mjs","language":"javascript","purpose":"Three offline migration invariants"},{"path":"package.json","language":"json","purpose":"Dependency-free execution commands"}],"samples":[{"language":"javascript","label":"JavaScript","code":"// Structural projection only: add semantic mappings after entitled validation.\nconst targetParameters=new Set([\"query:dataStoreName\",\"query:datasetNme\"]);\nconst targetBody=new Set([]);\nconst requiredParameters=[\"query:datasetNme\"];\nconst requiredBody=[];\n\nconst project=(source,allowed)=>Object.fromEntries(Object.entries(source??{}).filter(([key])=>allowed.has(key)));\nexport function adapt(source={}){\n  const parameters=project(source.parameters,targetParameters);\n  const body=project(source.body,targetBody);\n  const missing=[...requiredParameters.filter(key=>parameters[key]==null),...requiredBody.filter(key=>body[key]==null)];\n  return {target:{parameters,body},missing,dropped:{parameters:Object.keys(source.parameters??{}).filter(key=>!targetParameters.has(key)),body:Object.keys(source.body??{}).filter(key=>!targetBody.has(key))}};\n}"},{"language":"python","label":"Python","code":"# Structural projection only: add semantic mappings after entitled validation.\nTARGET_PARAMETERS=set([\"query:dataStoreName\",\"query:datasetNme\"])\nTARGET_BODY=set([])\nREQUIRED_PARAMETERS=[\"query:datasetNme\"]\nREQUIRED_BODY=[]\n\ndef adapt(source):\n    source_parameters=source.get(\"parameters\", {})\n    source_body=source.get(\"body\", {})\n    parameters={key:value for key,value in source_parameters.items() if key in TARGET_PARAMETERS}\n    body={key:value for key,value in source_body.items() if key in TARGET_BODY}\n    missing=[key for key in REQUIRED_PARAMETERS if parameters.get(key) is None]\n    missing += [key for key in REQUIRED_BODY if body.get(key) is None]\n    return {\"target\":{\"parameters\":parameters,\"body\":body},\"missing\":missing,\"dropped\":{\"parameters\":[key for key in source_parameters if key not in TARGET_PARAMETERS],\"body\":[key for key in source_body if key not in TARGET_BODY]}}"},{"language":"java","label":"Java","code":"import java.util.*;\n\npublic final class MapplsGenerationAdapter {\n  private static final Set<String> TARGET_PARAMETERS=Set.of(\"query:dataStoreName\", \"query:datasetNme\");\n  private static final Set<String> TARGET_BODY=Set.of();\n  private static final List<String> REQUIRED_PARAMETERS=List.of(\"query:datasetNme\");\n  private static final List<String> REQUIRED_BODY=List.of();\n  public record Envelope(Map<String,Object> parameters,Map<String,Object> body){}\n  public record Result(Envelope target,List<String> missing,List<String> droppedParameters,List<String> droppedBody){}\n  // Structural projection only: add semantic mappings after entitled validation.\n  private static Map<String,Object> project(Map<String,Object> source,Set<String> allowed){\n    var out=new LinkedHashMap<String,Object>();\n    source.forEach((key,value)->{if(allowed.contains(key))out.put(key,value);});\n    return out;\n  }\n  public static Result adapt(Envelope source){\n    var parameters=project(source.parameters(),TARGET_PARAMETERS);\n    var body=project(source.body(),TARGET_BODY);\n    var missing=new ArrayList<String>();\n    REQUIRED_PARAMETERS.stream().filter(key->parameters.get(key)==null).forEach(missing::add);\n    REQUIRED_BODY.stream().filter(key->body.get(key)==null).forEach(missing::add);\n    return new Result(new Envelope(parameters,body),missing,\n      source.parameters().keySet().stream().filter(key->!TARGET_PARAMETERS.contains(key)).toList(),\n      source.body().keySet().stream().filter(key->!TARGET_BODY.contains(key)).toList());\n  }\n}"},{"language":"csharp","label":"C#","code":"using System.Collections.Generic;\nusing System.Linq;\n\npublic static class MapplsGenerationAdapter {\n  static readonly HashSet<string> TargetParameters=new([\"query:dataStoreName\", \"query:datasetNme\"]);\n  static readonly HashSet<string> TargetBody=new([]);\n  static readonly string[] RequiredParameters=[\"query:datasetNme\"];\n  static readonly string[] RequiredBody=[];\n  public sealed record Envelope(Dictionary<string,object?> Parameters,Dictionary<string,object?> Body);\n  public sealed record Result(Envelope Target,string[] Missing,string[] DroppedParameters,string[] DroppedBody);\n  // Structural projection only: add semantic mappings after entitled validation.\n  static Dictionary<string,object?> Project(Dictionary<string,object?> source,HashSet<string> allowed)\n    =>source.Where(pair=>allowed.Contains(pair.Key)).ToDictionary();\n  public static Result Adapt(Envelope source){\n    var parameters=Project(source.Parameters,TargetParameters);\n    var body=Project(source.Body,TargetBody);\n    var missing=RequiredParameters.Where(key=>!parameters.TryGetValue(key,out var value)||value is null)\n      .Concat(RequiredBody.Where(key=>!body.TryGetValue(key,out var value)||value is null)).ToArray();\n    return new(new(parameters,body),missing,\n      source.Parameters.Keys.Where(key=>!TargetParameters.Contains(key)).ToArray(),\n      source.Body.Keys.Where(key=>!TargetBody.Contains(key)).ToArray());\n  }\n}"},{"language":"go","label":"Go","code":"package migration\n\n// Structural projection only: add semantic mappings after entitled validation.\nvar targetParameters=map[string]bool{\"query:dataStoreName\":true,\"query:datasetNme\":true}\nvar targetBody=map[string]bool{}\nvar requiredParameters=[]string{\"query:datasetNme\"}\nvar requiredBody=[]string{}\ntype Envelope struct { Parameters map[string]any; Body map[string]any }\ntype Result struct { Target Envelope; Missing,DroppedParameters,DroppedBody []string }\nfunc project(source map[string]any,allowed map[string]bool)(map[string]any,[]string){\n  out:=map[string]any{};dropped:=[]string{}\n  for key,value:=range source { if allowed[key] { out[key]=value } else { dropped=append(dropped,key) } }\n  return out,dropped\n}\nfunc Adapt(source Envelope)Result{\n  parameters,droppedParameters:=project(source.Parameters,targetParameters)\n  body,droppedBody:=project(source.Body,targetBody)\n  missing:=[]string{}\n  for _,key:=range requiredParameters { if parameters[key]==nil { missing=append(missing,key) } }\n  for _,key:=range requiredBody { if body[key]==nil { missing=append(missing,key) } }\n  return Result{Envelope{parameters,body},missing,droppedParameters,droppedBody}\n}"},{"language":"php","label":"PHP","code":"<?php\nconst TARGET_PARAMETERS=[\"query:dataStoreName\",\"query:datasetNme\"];\nconst TARGET_BODY=[];\nconst REQUIRED_PARAMETERS=[\"query:datasetNme\"];\nconst REQUIRED_BODY=[];\n// Structural projection only: add semantic mappings after entitled validation.\nfunction project(array $source,array $allowed):array{\n  return array_intersect_key($source,array_flip($allowed));\n}\nfunction adapt(array $source):array{\n  $sourceParameters=$source['parameters']??[];$sourceBody=$source['body']??[];\n  $parameters=project($sourceParameters,TARGET_PARAMETERS);$body=project($sourceBody,TARGET_BODY);\n  $missing=array_values(array_merge(\n    array_filter(REQUIRED_PARAMETERS,fn($key)=>!array_key_exists($key,$parameters)||$parameters[$key]===null),\n    array_filter(REQUIRED_BODY,fn($key)=>!array_key_exists($key,$body)||$body[$key]===null)\n  ));\n  return ['target'=>['parameters'=>$parameters,'body'=>$body],'missing'=>$missing,\n    'dropped'=>['parameters'=>array_values(array_diff(array_keys($sourceParameters),TARGET_PARAMETERS)),\n      'body'=>array_values(array_diff(array_keys($sourceBody),TARGET_BODY))]];\n}"},{"language":"ruby","label":"Ruby","code":"# Structural projection only: add semantic mappings after entitled validation.\nmodule MapplsGenerationAdapter\n  TARGET_PARAMETERS=[\"query:dataStoreName\",\"query:datasetNme\"].freeze\n  TARGET_BODY=[].freeze\n  REQUIRED_PARAMETERS=[\"query:datasetNme\"].freeze\n  REQUIRED_BODY=[].freeze\n  def self.project(source,allowed)\n    source.select{|key,_| allowed.include?(key)}\n  end\n  def self.adapt(source)\n    source_parameters=source.fetch(\"parameters\",{});source_body=source.fetch(\"body\",{})\n    parameters=project(source_parameters,TARGET_PARAMETERS);body=project(source_body,TARGET_BODY)\n    missing=REQUIRED_PARAMETERS.reject{|key| parameters.key?(key)&&!parameters[key].nil?}+REQUIRED_BODY.reject{|key| body.key?(key)&&!body[key].nil?}\n    {\"target\"=>{\"parameters\"=>parameters,\"body\"=>body},\"missing\"=>missing,\"dropped\"=>{\"parameters\"=>source_parameters.keys-TARGET_PARAMETERS,\"body\"=>source_body.keys-TARGET_BODY}}\n  end\nend"},{"language":"kotlin","label":"Kotlin","code":"data class Envelope(val parameters:Map<String,Any?>,val body:Map<String,Any?>)\ndata class MigrationResult(val target:Envelope,val missing:List<String>,val droppedParameters:List<String>,val droppedBody:List<String>)\nobject MapplsGenerationAdapter{\n  private val targetParameters=setOf(\"query:dataStoreName\", \"query:datasetNme\")\n  private val targetBody=setOf()\n  private val requiredParameters=listOf(\"query:datasetNme\")\n  private val requiredBody=listOf()\n  // Structural projection only: add semantic mappings after entitled validation.\n  fun adapt(source:Envelope):MigrationResult{\n    val parameters=source.parameters.filterKeys(targetParameters::contains)\n    val body=source.body.filterKeys(targetBody::contains)\n    val missing=requiredParameters.filter{parameters[it]==null}+requiredBody.filter{body[it]==null}\n    return MigrationResult(Envelope(parameters,body),missing,\n      source.parameters.keys.filterNot(targetParameters::contains),\n      source.body.keys.filterNot(targetBody::contains))\n  }\n}"}]}}