Raw Data

This file contains raw search retrieval results or agent logs. The content below shows the original markdown source.

---
layout: raw-data.njk
---
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>NZ Government API Catalogue - New Entry Form</title>
  <style>
    :root {
      --primary: #1a5a96;
      --primary-dark: #0d3d66;
      --border: #ccc;
      --bg-light: #f8f9fa;
      --text: #333;
      --text-muted: #666;
      --success: #28a745;
      --error: #dc3545;
    }

    * {
      box-sizing: border-box;
    }

    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
      line-height: 1.6;
      color: var(--text);
      max-width: 800px;
      margin: 0 auto;
      padding: 2rem;
      background: #fff;
    }

    header {
      margin-bottom: 2rem;
      padding-bottom: 1rem;
      border-bottom: 3px solid var(--primary);
    }

    h1 {
      color: var(--primary-dark);
      margin: 0 0 0.5rem 0;
      font-size: 1.75rem;
    }

    header p {
      color: var(--text-muted);
      margin: 0;
    }

    .section {
      background: var(--bg-light);
      border: 1px solid var(--border);
      border-radius: 8px;
      padding: 1.5rem;
      margin-bottom: 1.5rem;
    }

    .section h2 {
      margin: 0 0 1rem 0;
      font-size: 1.25rem;
      color: var(--primary-dark);
      padding-bottom: 0.5rem;
      border-bottom: 1px solid var(--border);
    }

    .section p.description {
      font-size: 0.9rem;
      color: var(--text-muted);
      margin: -0.5rem 0 1rem 0;
    }

    .field {
      margin-bottom: 1.25rem;
    }

    .field:last-child {
      margin-bottom: 0;
    }

    label {
      display: block;
      font-weight: 600;
      margin-bottom: 0.35rem;
      color: var(--text);
    }

    label .required {
      color: var(--error);
    }

    label .hint {
      font-weight: normal;
      color: var(--text-muted);
      font-size: 0.85rem;
    }

    input[type="text"],
    input[type="email"],
    input[type="url"],
    select,
    textarea {
      width: 100%;
      padding: 0.6rem 0.75rem;
      border: 1px solid var(--border);
      border-radius: 4px;
      font-size: 1rem;
      font-family: inherit;
      transition: border-color 0.2s, box-shadow 0.2s;
    }

    input:focus,
    select:focus,
    textarea:focus {
      outline: none;
      border-color: var(--primary);
      box-shadow: 0 0 0 3px rgba(26, 90, 150, 0.15);
    }

    textarea {
      min-height: 100px;
      resize: vertical;
    }

    select {
      background: #fff;
      cursor: pointer;
    }

    .checkbox-field {
      display: flex;
      align-items: flex-start;
      gap: 0.5rem;
    }

    .checkbox-field input[type="checkbox"] {
      margin-top: 0.25rem;
      width: auto;
    }

    .checkbox-field label {
      font-weight: normal;
      margin-bottom: 0;
    }

    .actions {
      display: flex;
      gap: 1rem;
      margin-top: 2rem;
    }

    button {
      padding: 0.75rem 1.5rem;
      font-size: 1rem;
      font-weight: 600;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      transition: background-color 0.2s;
    }

    button.primary {
      background: var(--primary);
      color: #fff;
    }

    button.primary:hover {
      background: var(--primary-dark);
    }

    button.secondary {
      background: #fff;
      color: var(--text);
      border: 1px solid var(--border);
    }

    button.secondary:hover {
      background: var(--bg-light);
    }

    .preview-section {
      margin-top: 2rem;
      display: none;
    }

    .preview-section.visible {
      display: block;
    }

    .preview-section h2 {
      color: var(--primary-dark);
      margin-bottom: 1rem;
    }

    .preview-content {
      background: #1e1e1e;
      color: #d4d4d4;
      padding: 1rem;
      border-radius: 8px;
      overflow-x: auto;
      font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
      font-size: 0.85rem;
      line-height: 1.5;
      white-space: pre-wrap;
      word-wrap: break-word;
    }

    .info-box {
      background: #e7f3ff;
      border: 1px solid #b6d4fe;
      border-radius: 4px;
      padding: 1rem;
      margin-bottom: 1.5rem;
      font-size: 0.9rem;
    }

    .info-box strong {
      color: var(--primary-dark);
    }

    footer {
      margin-top: 3rem;
      padding-top: 1rem;
      border-top: 1px solid var(--border);
      font-size: 0.85rem;
      color: var(--text-muted);
      text-align: center;
    }
  </style>
</head>
<body>

<header>
  <h1>NZ Government API Catalogue</h1>
  <p>New API Entry Submission Form</p>
</header>

<div class="info-box">
  <strong>How this works:</strong> Fill in the details below to generate a markdown file for your API entry. 
  The downloaded file can be submitted to GCDO@dia.govt.nz for inclusion in the catalogue, or added directly if you have edit access.
</div>

<form id="apiForm">

  <!-- Agency Section -->
  <div class="section">
    <h2>Agency Information</h2>
    <p class="description">Details about the government agency providing this API</p>
    
    <div class="field">
      <label for="agencyName">Agency Name <span class="required">*</span></label>
      <input type="text" id="agencyName" name="agencyName" required 
             placeholder="e.g., Ministry of Business, Innovation and Employment">
    </div>

    <div class="field">
      <label for="agencyAcronym">Agency Acronym <span class="required">*</span></label>
      <input type="text" id="agencyAcronym" name="agencyAcronym" required 
             placeholder="e.g., MBIE">
    </div>

    <div class="field">
      <label for="agencyEmail">Agency API Contact Email <span class="hint">(optional)</span></label>
      <input type="email" id="agencyEmail" name="agencyEmail" 
             placeholder="e.g., api-support@agency.govt.nz">
    </div>

    <div class="checkbox-field">
      <input type="checkbox" id="existingAgency" name="existingAgency">
      <label for="existingAgency">This agency already exists in the catalogue (only generate the API entry, not the agency header)</label>
    </div>
  </div>

  <!-- API Identity Section -->
  <div class="section">
    <h2>API Identity</h2>
    <p class="description">Core information about your API</p>

    <div class="field">
      <label for="apiName">API Name <span class="required">*</span></label>
      <input type="text" id="apiName" name="apiName" required 
             placeholder="e.g., Companies Register API">
    </div>

    <div class="field">
      <label for="apiDescription">Description <span class="required">*</span></label>
      <textarea id="apiDescription" name="apiDescription" required
                placeholder="Describe what the API does, what data or functionality it provides, and who might use it."></textarea>
    </div>

    <div class="field">
      <label for="apiEmail">API Contact Email <span class="hint">(optional)</span></label>
      <input type="email" id="apiEmail" name="apiEmail" 
             placeholder="e.g., companies-api@mbie.govt.nz">
    </div>
  </div>

  <!-- Classification Section -->
  <div class="section">
    <h2>Classification</h2>
    <p class="description">How the API is categorised and exposed</p>

    <div class="field">
      <label for="exposure">Exposure Level <span class="required">*</span></label>
      <select id="exposure" name="exposure" required>
        <option value="">-- Select exposure level --</option>
        <option value="public">Public - Available to anyone</option>
        <option value="external">External - Available to registered external consumers</option>
        <option value="partner">Partner - Available to approved partner organisations</option>
        <option value="internal">Internal - Government agency use only</option>
      </select>
    </div>

    <div class="field">
      <label for="apiType">API Type <span class="required">*</span></label>
      <select id="apiType" name="apiType" required>
        <option value="">-- Select API type --</option>
        <option value="REST">REST</option>
        <option value="GraphQL">GraphQL</option>
        <option value="AsyncAPI">AsyncAPI (event-driven)</option>
        <option value="gRPC">gRPC</option>
      </select>
    </div>
  </div>

  <!-- Access Section -->
  <div class="section">
    <h2>Access Information</h2>
    <p class="description">Where developers can find documentation and specifications</p>

    <div class="field">
      <label for="docsUrl">Documentation URL <span class="required">*</span></label>
      <input type="url" id="docsUrl" name="docsUrl" required 
             placeholder="e.g., https://portal.api.business.govt.nz/docs/companies">
    </div>

    <div class="field">
      <label for="specUrl">Specification URL <span class="hint">(optional - OpenAPI, AsyncAPI, etc.)</span></label>
      <input type="url" id="specUrl" name="specUrl" 
             placeholder="e.g., https://portal.api.business.govt.nz/specs/companies/openapi.yaml">
    </div>
  </div>

  <div class="actions">
    <button type="button" class="primary" onclick="generateAndDownload()">Download Markdown File</button>
    <button type="button" class="secondary" onclick="showPreview()">Preview Output</button>
    <button type="reset" class="secondary">Clear Form</button>
  </div>

</form>

<div id="previewSection" class="preview-section">
  <h2>Preview</h2>
  <div id="previewContent" class="preview-content"></div>
</div>

<footer>
  <p>NZ Government API Catalogue | Data Structure v1.0 | Phase 1 MVP</p>
  <p>Submit completed entries to <a href="mailto:GCDO@dia.govt.nz">GCDO@dia.govt.nz</a></p>
</footer>

<script>
function getFormData() {
  return {
    agencyName: document.getElementById('agencyName').value.trim(),
    agencyAcronym: document.getElementById('agencyAcronym').value.trim(),
    agencyEmail: document.getElementById('agencyEmail').value.trim() || null,
    existingAgency: document.getElementById('existingAgency').checked,
    apiName: document.getElementById('apiName').value.trim(),
    apiDescription: document.getElementById('apiDescription').value.trim(),
    apiEmail: document.getElementById('apiEmail').value.trim() || null,
    exposure: document.getElementById('exposure').value,
    apiType: document.getElementById('apiType').value,
    docsUrl: document.getElementById('docsUrl').value.trim(),
    specUrl: document.getElementById('specUrl').value.trim() || null
  };
}

function generateMarkdown(data) {
  let md = '';

  // Agency section (if not existing)
  if (!data.existingAgency) {
    const agencyIdentity = {
      name: data.agencyName,
      acronym: data.agencyAcronym,
      contact_email: data.agencyEmail
    };

    md += `---

## ${data.agencyName}

---

### Agency Information

---

#### identity

---

\`\`\`json
${JSON.stringify(agencyIdentity, null, 2)}
\`\`\`

`;
  }

  // API section
  const apiIdentity = {
    name: data.apiName,
    description: data.apiDescription,
    contact_email: data.apiEmail
  };

  const classification = {
    exposure: {
      value: data.exposure,
      allowed_values: ["internal", "external", "partner", "public"]
    },
    api_type: {
      value: data.apiType,
      allowed_values: ["REST", "GraphQL", "AsyncAPI", "gRPC"]
    }
  };

  const access = {
    docs_url: data.docsUrl,
    spec_url: data.specUrl
  };

  md += `---

### ${data.apiName}

---

#### identity

---

\`\`\`json
${JSON.stringify(apiIdentity, null, 2)}
\`\`\`

---

#### classification

---

\`\`\`json
${JSON.stringify(classification, null, 2)}
\`\`\`

---

#### access

---

\`\`\`json
${JSON.stringify(access, null, 2)}
\`\`\`
`;

  return md;
}

function validateForm() {
  const form = document.getElementById('apiForm');
  if (!form.checkValidity()) {
    form.reportValidity();
    return false;
  }
  return true;
}

function showPreview() {
  if (!validateForm()) return;
  
  const data = getFormData();
  const markdown = generateMarkdown(data);
  
  document.getElementById('previewContent').textContent = markdown;
  document.getElementById('previewSection').classList.add('visible');
  document.getElementById('previewSection').scrollIntoView({ behavior: 'smooth' });
}

function generateAndDownload() {
  if (!validateForm()) return;
  
  const data = getFormData();
  const markdown = generateMarkdown(data);
  
  // Generate filename from API name
  const filename = data.apiName
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-|-$/g, '') + '-api-entry.md';
  
  // Create and download file
  const blob = new Blob([markdown], { type: 'text/markdown;charset=utf-8' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}

// Auto-show preview on form changes
document.getElementById('apiForm').addEventListener('input', function() {
  const previewSection = document.getElementById('previewSection');
  if (previewSection.classList.contains('visible')) {
    const data = getFormData();
    if (data.apiName && data.apiDescription && data.exposure && data.apiType && data.docsUrl) {
      const markdown = generateMarkdown(data);
      document.getElementById('previewContent').textContent = markdown;
    }
  }
});
</script>

</body>
</html>