AgentSkillsCN

Documents

当您需要管理IT Glue文档时,可使用此技能:创建、整理并管理各类文档。本技能覆盖文档文件夹、嵌入式密码、相关物品、版本追踪,以及全面的客户文档管理最佳实践。

SKILL.md
--- frontmatter
description: >
  Use this skill when working with IT Glue documents - creating, organizing,
  and managing documentation. Covers document folders, embedded passwords,
  related items, version tracking, and documentation best practices for
  comprehensive client documentation management.
triggers:
  - it glue document
  - documentation
  - runbook
  - procedure documentation
  - it glue docs
  - document management
  - sop documentation
  - knowledge base

IT Glue Documents Management

Overview

Documents in IT Glue provide structured documentation storage for organizations, enabling technicians to create runbooks, procedures, network diagrams, and general documentation. Documents support rich HTML content, embedded passwords, and relationships to other IT Glue resources.

Key Concepts

Document Structure

Documents consist of:

  • Name - Document title
  • Content - Rich HTML content with embedded resources
  • Folder - Organizational hierarchy location
  • Related Items - Links to configurations, contacts, etc.

Document Folders

Folders provide hierarchical organization:

code
Organization: Acme Corporation
└── Documents
    ├── Onboarding
    │   ├── New User Setup
    │   └── Hardware Deployment
    ├── Procedures
    │   ├── Backup Procedures
    │   └── Disaster Recovery
    └── Network
        ├── Network Diagram
        └── IP Scheme

Embedded Resources

Documents can embed:

  • Passwords - Inline credential display
  • Configurations - Asset links
  • Contacts - Contact information
  • Images - Uploaded images/diagrams

Field Reference

Core Fields

FieldTypeRequiredDescription
idintegerSystemAuto-generated unique identifier
organization-idintegerYesParent organization
namestringYesDocument title
contentstringNoRich HTML content
document-folder-idintegerNoFolder location

Relationship Fields

FieldTypeDescription
resource-idintegerRelated resource ID
resource-typestringRelated resource type

Metadata Fields

FieldTypeDescription
created-atdatetimeCreation timestamp
updated-atdatetimeLast update timestamp

API Patterns

List Documents

http
GET /documents
x-api-key: YOUR_API_KEY
Content-Type: application/vnd.api+json

By Organization:

http
GET /organizations/123/relationships/documents

With Filters:

http
GET /documents?filter[organization-id]=123&filter[document-folder-id]=456

With Pagination:

http
GET /documents?page[size]=100&page[number]=1&sort=name

Get Single Document

http
GET /documents/789
x-api-key: YOUR_API_KEY

With Includes:

http
GET /documents/789?include=organization,document-folder,related-items

Create Document

http
POST /documents
Content-Type: application/vnd.api+json
x-api-key: YOUR_API_KEY
json
{
  "data": {
    "type": "documents",
    "attributes": {
      "organization-id": 123456,
      "name": "New User Setup Procedure",
      "document-folder-id": 789,
      "content": "<h1>New User Setup Procedure</h1><h2>Overview</h2><p>This procedure covers the steps for setting up a new user account.</p><h2>Prerequisites</h2><ul><li>Active Directory access</li><li>Microsoft 365 admin access</li></ul><h2>Steps</h2><ol><li>Create AD account</li><li>Assign Microsoft 365 license</li><li>Configure email signature</li></ol>"
    }
  }
}

Update Document

http
PATCH /documents/789
Content-Type: application/vnd.api+json
x-api-key: YOUR_API_KEY
json
{
  "data": {
    "type": "documents",
    "attributes": {
      "content": "<h1>Updated Content</h1><p>New procedure steps...</p>"
    }
  }
}

Delete Document

http
DELETE /documents/789
x-api-key: YOUR_API_KEY

Search Documents

By Name:

http
GET /documents?filter[name]=backup

By Folder:

http
GET /documents?filter[document-folder-id]=456

Document Folders

List Folders

http
GET /document-folders
x-api-key: YOUR_API_KEY

By Organization:

http
GET /organizations/123/relationships/document-folders

Create Folder

http
POST /document-folders
Content-Type: application/vnd.api+json
json
{
  "data": {
    "type": "document-folders",
    "attributes": {
      "organization-id": 123456,
      "name": "Procedures",
      "parent-id": null
    }
  }
}

Nested Folders

json
{
  "data": {
    "type": "document-folders",
    "attributes": {
      "organization-id": 123456,
      "name": "Disaster Recovery",
      "parent-id": 789
    }
  }
}

Embedding Resources

Embedded Passwords

Include password references in document content:

html
<h2>Login Credentials</h2>
<p>Domain Admin:</p>
<div data-embedded-password-id="12345"></div>

Embedded Configurations

Reference configurations in documents:

html
<h2>Related Servers</h2>
<div data-embedded-configuration-id="67890"></div>

Embedded Images

Include uploaded images:

html
<h2>Network Diagram</h2>
<img src="/uploads/organization/123/network-diagram.png" alt="Network Diagram">

Related Items

Create Related Item

http
POST /related-items
Content-Type: application/vnd.api+json
json
{
  "data": {
    "type": "related-items",
    "attributes": {
      "resource-id": 789,
      "resource-type": "Document",
      "destination-id": 456,
      "destination-type": "Configuration",
      "notes": "This document describes the configuration of this server"
    }
  }
}

List Related Items

http
GET /documents/789/relationships/related-items

Common Workflows

Create Comprehensive Runbook

javascript
async function createRunbook(orgId, runbookData) {
  // Ensure folder exists
  const folder = await ensureDocumentFolder(orgId, runbookData.folderPath);

  // Build content with embedded resources
  let content = `
    <h1>${runbookData.title}</h1>
    <h2>Overview</h2>
    <p>${runbookData.overview}</p>
  `;

  // Add prerequisites section
  if (runbookData.prerequisites?.length) {
    content += `
      <h2>Prerequisites</h2>
      <ul>${runbookData.prerequisites.map(p => `<li>${p}</li>`).join('')}</ul>
    `;
  }

  // Add procedure steps
  if (runbookData.steps?.length) {
    content += `
      <h2>Procedure</h2>
      <ol>${runbookData.steps.map(s => `<li>${s}</li>`).join('')}</ol>
    `;
  }

  // Embed related passwords
  if (runbookData.passwordIds?.length) {
    content += `
      <h2>Required Credentials</h2>
      ${runbookData.passwordIds.map(id =>
        `<div data-embedded-password-id="${id}"></div>`
      ).join('')}
    `;
  }

  // Create the document
  const doc = await createDocument({
    'organization-id': orgId,
    name: runbookData.title,
    'document-folder-id': folder?.id,
    content: content
  });

  // Create related items
  for (const configId of runbookData.relatedConfigs || []) {
    await createRelatedItem({
      'resource-id': doc.id,
      'resource-type': 'Document',
      'destination-id': configId,
      'destination-type': 'Configuration'
    });
  }

  return doc;
}

Document Search

javascript
async function searchDocuments(orgId, query) {
  const docs = await fetchDocuments({
    filter: { 'organization-id': orgId }
  });

  const queryLower = query.toLowerCase();
  return docs.filter(doc =>
    doc.attributes.name.toLowerCase().includes(queryLower) ||
    doc.attributes.content?.toLowerCase().includes(queryLower)
  );
}

Export Documentation

javascript
async function exportOrgDocumentation(orgId) {
  const docs = await fetchDocuments({
    filter: { 'organization-id': orgId },
    include: 'document-folder'
  });

  return docs.map(doc => ({
    name: doc.attributes.name,
    folder: doc.included?.find(i =>
      i.type === 'document-folders' &&
      i.id === doc.relationships['document-folder']?.data?.id
    )?.attributes?.name || 'Root',
    content: doc.attributes.content,
    createdAt: doc.attributes['created-at'],
    updatedAt: doc.attributes['updated-at']
  }));
}

Documentation Health Check

javascript
async function documentationHealthCheck(orgId) {
  const docs = await fetchDocuments({
    filter: { 'organization-id': orgId }
  });

  const thirtyDaysAgo = new Date();
  thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

  return {
    totalDocuments: docs.length,
    recentlyUpdated: docs.filter(d =>
      new Date(d.attributes['updated-at']) > thirtyDaysAgo
    ).length,
    stale: docs.filter(d => {
      const updated = new Date(d.attributes['updated-at']);
      const yearAgo = new Date();
      yearAgo.setFullYear(yearAgo.getFullYear() - 1);
      return updated < yearAgo;
    }).map(d => ({
      name: d.attributes.name,
      lastUpdated: d.attributes['updated-at']
    })),
    empty: docs.filter(d =>
      !d.attributes.content || d.attributes.content.trim().length < 50
    ).map(d => d.attributes.name)
  };
}

Clone Document Template

javascript
async function cloneDocumentToOrg(templateDocId, targetOrgId, newName) {
  // Get template document
  const template = await getDocument(templateDocId);

  // Create new document with template content
  return await createDocument({
    'organization-id': targetOrgId,
    name: newName || template.attributes.name,
    content: template.attributes.content
  });
}

Document Templates

Standard Documentation Structure

Network Overview:

html
<h1>Network Overview</h1>

<h2>Network Topology</h2>
<p>[Network diagram embedded here]</p>

<h2>IP Addressing</h2>
<table>
  <tr><th>Subnet</th><th>VLAN</th><th>Purpose</th></tr>
  <tr><td>192.168.1.0/24</td><td>1</td><td>Servers</td></tr>
  <tr><td>192.168.10.0/24</td><td>10</td><td>Workstations</td></tr>
</table>

<h2>Core Infrastructure</h2>
<p>[Embedded configuration items]</p>

<h2>Firewall Rules Summary</h2>
<p>[Rule overview]</p>

<h2>Related Credentials</h2>
<p>[Embedded passwords]</p>

Disaster Recovery:

html
<h1>Disaster Recovery Plan</h1>

<h2>Contact Information</h2>
<p>[Primary contacts embedded]</p>

<h2>Critical Systems</h2>
<ol>
  <li>Domain Controller</li>
  <li>Email Server</li>
  <li>File Server</li>
</ol>

<h2>Recovery Procedures</h2>
<h3>Complete Site Failure</h3>
<ol>
  <li>Activate backup site</li>
  <li>Restore from cloud backup</li>
  <li>Verify DNS failover</li>
</ol>

<h2>Required Credentials</h2>
<p>[Recovery passwords embedded]</p>

<h2>Vendor Contacts</h2>
<p>[Vendor contact information]</p>

Error Handling

Common API Errors

CodeMessageResolution
400Name can't be blankProvide document name
400Organization requiredInclude organization-id
401Invalid API keyCheck IT_GLUE_API_KEY
404Document not foundVerify document ID
422Invalid folderQuery valid folder IDs

Validation Errors

ErrorCauseFix
Name requiredMissing nameAdd name to request
Organization requiredNo org IDInclude organization-id
Invalid folderBad folder IDQuery /document-folders
Content too largeExceeds size limitReduce content size

Error Recovery Pattern

javascript
async function safeCreateDocument(data) {
  try {
    return await createDocument(data);
  } catch (error) {
    if (error.status === 422) {
      const errors = error.errors || [];

      // Handle invalid folder
      if (errors.some(e => e.detail?.includes('folder'))) {
        console.log('Invalid folder. Creating at root level.');
        delete data['document-folder-id'];
        return await createDocument(data);
      }
    }

    throw error;
  }
}

Best Practices

  1. Use consistent structure - Follow templates for standard documents
  2. Organize with folders - Create logical folder hierarchy
  3. Keep content current - Review and update regularly
  4. Embed credentials - Use embedded passwords instead of plain text
  5. Link related items - Connect documents to configurations
  6. Use meaningful names - Clear, descriptive document titles
  7. Include metadata - Add last reviewed date, author, version
  8. Standardize formatting - Consistent headings and structure
  9. Add visual aids - Include diagrams and screenshots
  10. Regular audits - Review documentation quarterly

Related Skills