datadrivenconstruction

as-built-documentation

6
6
# Install this skill:
npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction

Or install specific skill: npx add-skill https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction/tree/main/5_DDC_Innovative/as-built-documentation

# Description

Automate as-built documentation and digital handover for construction. Compile project records, generate O&M manuals, create asset databases, and ensure complete project closeout.

# SKILL.md


name: as-built-documentation
description: "Automate as-built documentation and digital handover for construction. Compile project records, generate O&M manuals, create asset databases, and ensure complete project closeout."


As-Built Documentation

Overview

This skill implements automated as-built documentation and digital handover for construction projects. Compile accurate records, generate operation manuals, and ensure complete documentation for facility management.

Capabilities:
- As-built drawing management
- O&M manual generation
- Asset data compilation
- Warranty tracking
- Document organization
- BIM-to-FM handover

Quick Start

from dataclasses import dataclass, field
from datetime import date, datetime
from typing import List, Dict, Optional
from enum import Enum

class DocumentType(Enum):
    DRAWING = "drawing"
    SPECIFICATION = "specification"
    SUBMITTAL = "submittal"
    WARRANTY = "warranty"
    CERTIFICATE = "certificate"
    MANUAL = "manual"
    TEST_REPORT = "test_report"
    COMMISSIONING = "commissioning"
    PHOTO = "photo"

class DocumentStatus(Enum):
    DRAFT = "draft"
    REVIEWED = "reviewed"
    APPROVED = "approved"
    AS_BUILT = "as_built"
    FINAL = "final"

@dataclass
class HandoverDocument:
    doc_id: str
    doc_type: DocumentType
    title: str
    file_path: str
    version: str
    status: DocumentStatus
    system: str  # Building system (HVAC, Electrical, etc.)
    uploaded_date: date
    approved_by: str = ""

@dataclass
class AssetRecord:
    asset_id: str
    asset_name: str
    asset_type: str
    manufacturer: str
    model: str
    serial_number: str
    location: str
    install_date: date
    warranty_end: date
    documents: List[str] = field(default_factory=list)

def check_handover_completeness(documents: List[HandoverDocument],
                                required_types: List[DocumentType]) -> Dict:
    """Check if all required documents are present"""
    present_types = {doc.doc_type for doc in documents if doc.status == DocumentStatus.FINAL}
    missing = set(required_types) - present_types

    return {
        'complete': len(missing) == 0,
        'total_required': len(required_types),
        'total_present': len(present_types),
        'missing_types': [t.value for t in missing]
    }

# Example
documents = [
    HandoverDocument("DOC-001", DocumentType.DRAWING, "Floor Plans As-Built",
                    "/docs/floorplans.pdf", "3.0", DocumentStatus.FINAL, "Architecture", date.today()),
    HandoverDocument("DOC-002", DocumentType.MANUAL, "HVAC O&M Manual",
                    "/docs/hvac_om.pdf", "1.0", DocumentStatus.FINAL, "HVAC", date.today()),
]

required = [DocumentType.DRAWING, DocumentType.MANUAL, DocumentType.WARRANTY]
status = check_handover_completeness(documents, required)
print(f"Complete: {status['complete']}, Missing: {status['missing_types']}")

Comprehensive Handover System

Document Management

from dataclasses import dataclass, field
from datetime import date, datetime, timedelta
from typing import List, Dict, Optional, Tuple
from enum import Enum
import uuid
import os

class BuildingSystem(Enum):
    ARCHITECTURAL = "architectural"
    STRUCTURAL = "structural"
    MECHANICAL = "mechanical"
    ELECTRICAL = "electrical"
    PLUMBING = "plumbing"
    FIRE_PROTECTION = "fire_protection"
    CONTROLS = "controls"
    ELEVATOR = "elevator"
    CIVIL = "civil"
    LANDSCAPE = "landscape"

@dataclass
class DocumentRequirement:
    requirement_id: str
    doc_type: DocumentType
    system: BuildingSystem
    description: str
    is_mandatory: bool = True
    quantity: int = 1  # How many documents of this type needed
    format_requirements: str = "PDF"

@dataclass
class ProjectDocument:
    doc_id: str
    requirement_id: Optional[str]
    doc_type: DocumentType
    system: BuildingSystem
    title: str
    description: str
    file_path: str
    file_size_mb: float
    format: str
    version: str
    revision_date: date
    author: str
    reviewer: str
    status: DocumentStatus
    metadata: Dict = field(default_factory=dict)
    related_assets: List[str] = field(default_factory=list)
    supersedes: Optional[str] = None  # Previous version doc_id

class DocumentManager:
    """Manage project handover documents"""

    STANDARD_REQUIREMENTS = {
        BuildingSystem.MECHANICAL: [
            DocumentRequirement("REQ-M01", DocumentType.DRAWING, BuildingSystem.MECHANICAL,
                              "HVAC As-Built Drawings"),
            DocumentRequirement("REQ-M02", DocumentType.MANUAL, BuildingSystem.MECHANICAL,
                              "HVAC Operation & Maintenance Manual"),
            DocumentRequirement("REQ-M03", DocumentType.WARRANTY, BuildingSystem.MECHANICAL,
                              "HVAC Equipment Warranties"),
            DocumentRequirement("REQ-M04", DocumentType.TEST_REPORT, BuildingSystem.MECHANICAL,
                              "TAB Report - Testing, Adjusting, Balancing"),
            DocumentRequirement("REQ-M05", DocumentType.COMMISSIONING, BuildingSystem.MECHANICAL,
                              "Commissioning Report"),
        ],
        BuildingSystem.ELECTRICAL: [
            DocumentRequirement("REQ-E01", DocumentType.DRAWING, BuildingSystem.ELECTRICAL,
                              "Electrical As-Built Drawings"),
            DocumentRequirement("REQ-E02", DocumentType.MANUAL, BuildingSystem.ELECTRICAL,
                              "Electrical O&M Manual"),
            DocumentRequirement("REQ-E03", DocumentType.WARRANTY, BuildingSystem.ELECTRICAL,
                              "Electrical Equipment Warranties"),
            DocumentRequirement("REQ-E04", DocumentType.TEST_REPORT, BuildingSystem.ELECTRICAL,
                              "Electrical Test Reports"),
            DocumentRequirement("REQ-E05", DocumentType.CERTIFICATE, BuildingSystem.ELECTRICAL,
                              "Electrical Inspection Certificate"),
        ],
        BuildingSystem.PLUMBING: [
            DocumentRequirement("REQ-P01", DocumentType.DRAWING, BuildingSystem.PLUMBING,
                              "Plumbing As-Built Drawings"),
            DocumentRequirement("REQ-P02", DocumentType.MANUAL, BuildingSystem.PLUMBING,
                              "Plumbing O&M Manual"),
            DocumentRequirement("REQ-P03", DocumentType.TEST_REPORT, BuildingSystem.PLUMBING,
                              "Pressure Test Reports"),
        ],
        BuildingSystem.FIRE_PROTECTION: [
            DocumentRequirement("REQ-F01", DocumentType.DRAWING, BuildingSystem.FIRE_PROTECTION,
                              "Fire Protection As-Built Drawings"),
            DocumentRequirement("REQ-F02", DocumentType.MANUAL, BuildingSystem.FIRE_PROTECTION,
                              "Fire Systems O&M Manual"),
            DocumentRequirement("REQ-F03", DocumentType.CERTIFICATE, BuildingSystem.FIRE_PROTECTION,
                              "Fire Marshal Approval"),
            DocumentRequirement("REQ-F04", DocumentType.TEST_REPORT, BuildingSystem.FIRE_PROTECTION,
                              "Fire Alarm Acceptance Test"),
        ],
        BuildingSystem.ARCHITECTURAL: [
            DocumentRequirement("REQ-A01", DocumentType.DRAWING, BuildingSystem.ARCHITECTURAL,
                              "Architectural As-Built Drawings"),
            DocumentRequirement("REQ-A02", DocumentType.SPECIFICATION, BuildingSystem.ARCHITECTURAL,
                              "Finish Schedule"),
            DocumentRequirement("REQ-A03", DocumentType.WARRANTY, BuildingSystem.ARCHITECTURAL,
                              "Roofing Warranty"),
        ]
    }

    def __init__(self, project_id: str, project_name: str):
        self.project_id = project_id
        self.project_name = project_name
        self.requirements: Dict[str, DocumentRequirement] = {}
        self.documents: Dict[str, ProjectDocument] = {}
        self._load_standard_requirements()

    def _load_standard_requirements(self):
        """Load standard document requirements"""
        for system, reqs in self.STANDARD_REQUIREMENTS.items():
            for req in reqs:
                self.requirements[req.requirement_id] = req

    def add_requirement(self, requirement: DocumentRequirement):
        """Add custom requirement"""
        self.requirements[requirement.requirement_id] = requirement

    def upload_document(self, doc_type: DocumentType, system: BuildingSystem,
                       title: str, file_path: str, author: str,
                       requirement_id: str = None,
                       related_assets: List[str] = None) -> ProjectDocument:
        """Upload new document"""
        doc_id = f"DOC-{uuid.uuid4().hex[:8].upper()}"

        # Get file info
        file_size = os.path.getsize(file_path) / (1024 * 1024) if os.path.exists(file_path) else 0
        file_format = os.path.splitext(file_path)[1].upper().replace('.', '')

        doc = ProjectDocument(
            doc_id=doc_id,
            requirement_id=requirement_id,
            doc_type=doc_type,
            system=system,
            title=title,
            description="",
            file_path=file_path,
            file_size_mb=file_size,
            format=file_format,
            version="1.0",
            revision_date=date.today(),
            author=author,
            reviewer="",
            status=DocumentStatus.DRAFT,
            related_assets=related_assets or []
        )

        self.documents[doc_id] = doc
        return doc

    def approve_document(self, doc_id: str, reviewer: str) -> bool:
        """Approve document"""
        doc = self.documents.get(doc_id)
        if doc:
            doc.status = DocumentStatus.APPROVED
            doc.reviewer = reviewer
            return True
        return False

    def finalize_document(self, doc_id: str) -> bool:
        """Finalize document for handover"""
        doc = self.documents.get(doc_id)
        if doc and doc.status == DocumentStatus.APPROVED:
            doc.status = DocumentStatus.FINAL
            return True
        return False

    def get_status_summary(self) -> Dict:
        """Get document status summary"""
        summary = {
            'total_requirements': len(self.requirements),
            'total_documents': len(self.documents),
            'by_status': {},
            'by_system': {},
            'completion': {}
        }

        # Count by status
        for doc in self.documents.values():
            status = doc.status.value
            summary['by_status'][status] = summary['by_status'].get(status, 0) + 1

            system = doc.system.value
            if system not in summary['by_system']:
                summary['by_system'][system] = {'uploaded': 0, 'final': 0}
            summary['by_system'][system]['uploaded'] += 1
            if doc.status == DocumentStatus.FINAL:
                summary['by_system'][system]['final'] += 1

        # Check completion against requirements
        for req_id, req in self.requirements.items():
            matching_docs = [
                d for d in self.documents.values()
                if d.requirement_id == req_id and d.status == DocumentStatus.FINAL
            ]

            summary['completion'][req_id] = {
                'description': req.description,
                'system': req.system.value,
                'required': req.quantity,
                'submitted': len(matching_docs),
                'complete': len(matching_docs) >= req.quantity
            }

        return summary

    def get_missing_documents(self) -> List[DocumentRequirement]:
        """Get list of missing required documents"""
        missing = []

        for req_id, req in self.requirements.items():
            if not req.is_mandatory:
                continue

            matching_docs = [
                d for d in self.documents.values()
                if d.requirement_id == req_id and d.status == DocumentStatus.FINAL
            ]

            if len(matching_docs) < req.quantity:
                missing.append(req)

        return missing

Asset Registry

from datetime import date, timedelta
from typing import List, Dict, Optional

@dataclass
class MaintenanceSchedule:
    schedule_id: str
    task_description: str
    frequency: str  # daily, weekly, monthly, quarterly, annual
    next_due: date
    responsible_party: str
    estimated_duration_hours: float

@dataclass
class AssetDetails:
    asset_id: str
    asset_tag: str
    asset_name: str
    asset_type: str
    category: str  # equipment, fixture, system

    # Identification
    manufacturer: str
    model_number: str
    serial_number: str
    part_number: str = ""

    # Location
    building: str = ""
    floor: str = ""
    room: str = ""
    coordinates: Tuple[float, float, float] = (0, 0, 0)

    # Installation
    install_date: date = None
    installed_by: str = ""
    cost: float = 0

    # Warranty
    warranty_start: date = None
    warranty_end: date = None
    warranty_provider: str = ""
    warranty_terms: str = ""

    # Specifications
    specifications: Dict = field(default_factory=dict)

    # Documents
    manuals: List[str] = field(default_factory=list)
    drawings: List[str] = field(default_factory=list)
    photos: List[str] = field(default_factory=list)

    # Maintenance
    maintenance_schedules: List[MaintenanceSchedule] = field(default_factory=list)
    service_contacts: List[Dict] = field(default_factory=list)

    # BIM reference
    ifc_guid: str = ""
    revit_element_id: str = ""

class AssetRegistry:
    """Manage building assets for handover"""

    def __init__(self, project_id: str):
        self.project_id = project_id
        self.assets: Dict[str, AssetDetails] = {}

    def register_asset(self, asset: AssetDetails):
        """Register new asset"""
        self.assets[asset.asset_id] = asset

    def import_from_bim(self, bim_data: List[Dict]):
        """Import assets from BIM model"""
        for item in bim_data:
            asset = AssetDetails(
                asset_id=f"AST-{uuid.uuid4().hex[:8].upper()}",
                asset_tag=item.get('tag', ''),
                asset_name=item.get('name', ''),
                asset_type=item.get('type', ''),
                category=item.get('category', 'equipment'),
                manufacturer=item.get('manufacturer', ''),
                model_number=item.get('model', ''),
                serial_number=item.get('serial', ''),
                building=item.get('building', ''),
                floor=item.get('floor', ''),
                room=item.get('room', ''),
                ifc_guid=item.get('ifc_guid', ''),
                revit_element_id=item.get('revit_id', '')
            )

            # Add specifications
            for key, value in item.get('parameters', {}).items():
                asset.specifications[key] = value

            self.assets[asset.asset_id] = asset

    def add_warranty(self, asset_id: str, start_date: date,
                    duration_years: int, provider: str, terms: str = ""):
        """Add warranty information"""
        asset = self.assets.get(asset_id)
        if asset:
            asset.warranty_start = start_date
            asset.warranty_end = start_date + timedelta(days=365 * duration_years)
            asset.warranty_provider = provider
            asset.warranty_terms = terms

    def add_maintenance_schedule(self, asset_id: str,
                                 schedule: MaintenanceSchedule):
        """Add maintenance schedule"""
        asset = self.assets.get(asset_id)
        if asset:
            asset.maintenance_schedules.append(schedule)

    def get_warranty_report(self) -> Dict:
        """Get warranty status report"""
        today = date.today()

        report = {
            'total_assets': len(self.assets),
            'with_warranty': 0,
            'active_warranties': 0,
            'expiring_soon': [],  # Within 90 days
            'expired': []
        }

        for asset in self.assets.values():
            if asset.warranty_end:
                report['with_warranty'] += 1

                if asset.warranty_end >= today:
                    report['active_warranties'] += 1

                    days_remaining = (asset.warranty_end - today).days
                    if days_remaining <= 90:
                        report['expiring_soon'].append({
                            'asset_id': asset.asset_id,
                            'asset_name': asset.asset_name,
                            'warranty_end': asset.warranty_end.isoformat(),
                            'days_remaining': days_remaining
                        })
                else:
                    report['expired'].append({
                        'asset_id': asset.asset_id,
                        'asset_name': asset.asset_name,
                        'warranty_end': asset.warranty_end.isoformat()
                    })

        return report

    def export_to_cmms(self) -> List[Dict]:
        """Export assets for CMMS import"""
        export_data = []

        for asset in self.assets.values():
            export_data.append({
                'asset_id': asset.asset_id,
                'asset_tag': asset.asset_tag,
                'name': asset.asset_name,
                'type': asset.asset_type,
                'category': asset.category,
                'manufacturer': asset.manufacturer,
                'model': asset.model_number,
                'serial': asset.serial_number,
                'location': f"{asset.building}/{asset.floor}/{asset.room}",
                'install_date': asset.install_date.isoformat() if asset.install_date else '',
                'warranty_end': asset.warranty_end.isoformat() if asset.warranty_end else '',
                'specifications': asset.specifications
            })

        return export_data

O&M Manual Generator

class OMManualGenerator:
    """Generate O&M manuals from project data"""

    def __init__(self, doc_manager: DocumentManager, asset_registry: AssetRegistry):
        self.docs = doc_manager
        self.assets = asset_registry

    def generate_system_manual(self, system: BuildingSystem,
                              output_path: str) -> Dict:
        """Generate O&M manual for building system"""
        # Collect system documents
        system_docs = [
            d for d in self.docs.documents.values()
            if d.system == system and d.status == DocumentStatus.FINAL
        ]

        # Collect system assets
        system_assets = [
            a for a in self.assets.assets.values()
            if a.asset_type.lower() in system.value.lower() or
               system.value.lower() in a.category.lower()
        ]

        manual_content = {
            'system': system.value,
            'generated_date': date.today().isoformat(),
            'sections': []
        }

        # Section 1: System Overview
        manual_content['sections'].append({
            'title': 'System Overview',
            'content': f"Overview of {system.value} system",
            'subsections': []
        })

        # Section 2: Equipment List
        equipment_list = []
        for asset in system_assets:
            equipment_list.append({
                'tag': asset.asset_tag,
                'name': asset.asset_name,
                'manufacturer': asset.manufacturer,
                'model': asset.model_number,
                'location': f"{asset.building}/{asset.floor}/{asset.room}"
            })

        manual_content['sections'].append({
            'title': 'Equipment Schedule',
            'equipment': equipment_list
        })

        # Section 3: Operation Procedures
        manual_content['sections'].append({
            'title': 'Operation Procedures',
            'content': 'Standard operating procedures',
            'reference_docs': [d.doc_id for d in system_docs if d.doc_type == DocumentType.MANUAL]
        })

        # Section 4: Maintenance Requirements
        maintenance_tasks = []
        for asset in system_assets:
            for schedule in asset.maintenance_schedules:
                maintenance_tasks.append({
                    'asset': asset.asset_name,
                    'task': schedule.task_description,
                    'frequency': schedule.frequency,
                    'duration': schedule.estimated_duration_hours
                })

        manual_content['sections'].append({
            'title': 'Preventive Maintenance',
            'tasks': maintenance_tasks
        })

        # Section 5: Warranty Information
        warranties = []
        for asset in system_assets:
            if asset.warranty_end:
                warranties.append({
                    'asset': asset.asset_name,
                    'provider': asset.warranty_provider,
                    'expires': asset.warranty_end.isoformat(),
                    'terms': asset.warranty_terms
                })

        manual_content['sections'].append({
            'title': 'Warranty Information',
            'warranties': warranties
        })

        # Section 6: Service Contacts
        contacts = []
        for asset in system_assets:
            contacts.extend(asset.service_contacts)

        manual_content['sections'].append({
            'title': 'Service Contacts',
            'contacts': list({c['name']: c for c in contacts}.values())
        })

        # Section 7: Reference Documents
        manual_content['sections'].append({
            'title': 'Reference Documents',
            'documents': [
                {'id': d.doc_id, 'title': d.title, 'type': d.doc_type.value}
                for d in system_docs
            ]
        })

        return manual_content

    def generate_building_manual(self, output_path: str) -> Dict:
        """Generate complete building O&M manual"""
        building_manual = {
            'project': self.docs.project_name,
            'generated': date.today().isoformat(),
            'systems': {}
        }

        for system in BuildingSystem:
            building_manual['systems'][system.value] = self.generate_system_manual(
                system, output_path
            )

        return building_manual

Handover Checklist

def generate_handover_checklist(doc_manager: DocumentManager,
                               asset_registry: AssetRegistry) -> Dict:
    """Generate comprehensive handover checklist"""
    checklist = {
        'generated': date.today().isoformat(),
        'project': doc_manager.project_name,
        'overall_status': 'incomplete',
        'categories': []
    }

    # Documents category
    doc_status = doc_manager.get_status_summary()
    missing_docs = doc_manager.get_missing_documents()

    checklist['categories'].append({
        'name': 'Documents',
        'complete': len(missing_docs) == 0,
        'items': [
            {
                'item': req.description,
                'system': req.system.value,
                'status': 'complete' if req.requirement_id not in [m.requirement_id for m in missing_docs] else 'missing'
            }
            for req in doc_manager.requirements.values()
        ]
    })

    # Assets category
    warranty_report = asset_registry.get_warranty_report()

    checklist['categories'].append({
        'name': 'Asset Registration',
        'complete': warranty_report['total_assets'] > 0,
        'items': [
            {'item': 'All major equipment registered', 'status': 'complete' if warranty_report['total_assets'] > 0 else 'incomplete'},
            {'item': 'Warranty information entered', 'status': 'complete' if warranty_report['with_warranty'] > 0 else 'incomplete'},
            {'item': 'Maintenance schedules defined', 'status': 'complete' if any(a.maintenance_schedules for a in asset_registry.assets.values()) else 'incomplete'}
        ]
    })

    # Training category
    checklist['categories'].append({
        'name': 'Training',
        'complete': False,
        'items': [
            {'item': 'Operations staff training completed', 'status': 'pending'},
            {'item': 'Maintenance staff training completed', 'status': 'pending'},
            {'item': 'Safety systems training completed', 'status': 'pending'}
        ]
    })

    # Determine overall status
    all_complete = all(cat['complete'] for cat in checklist['categories'])
    checklist['overall_status'] = 'complete' if all_complete else 'incomplete'

    return checklist

Quick Reference

Document Type Typical Source When Required
As-Built Drawings Contractor Substantial completion
O&M Manuals Manufacturer/Contractor Before training
Warranties Manufacturers At installation
Test Reports Testing agency After testing
Certificates Authorities Final inspection
Training Records Contractor Before handover

Resources

  • COBie Standard: Construction Operations Building Information Exchange
  • ASHRAE Guideline 0: Commissioning process
  • IFMA: Facility Management resources
  • DDC Website: https://datadrivenconstruction.io

Next Steps

  • See bim-validation-pipeline for BIM handover
  • See document-classification-nlp for document processing
  • See digital-twin-sync for FM integration

# README.md

DDC Skills Collection for AI Coding Assistants

AI Tools for Construction Company Automation

Skills Categories Languages License

DDC Skills

Works with any AI coding assistant:

Claude Code Google Antigravity OpenCode ClawdBot


What is this?

A collection of 221 skills for automating construction company processes with AI coding assistants.

What is a "Skill"?

A skill is a SKILL.md file — structured instructions that an AI coding assistant can read and execute. Each skill describes a specific task: what problem it solves, what code to generate, and what tools are needed. You open a skill folder in your AI assistant, and it helps you implement the described functionality.


Collection Structure

Skills are organized by source and complexity level:

Category What's inside Skills Start here if...
1_DDC_Toolkit Production-ready tools: CWICR database, CAD converters, analytics 85 You need a working tool now
2_DDC_Book Skills mapped to book chapters: data evolution, types, estimation, ML 67 You want to follow a structured learning path
3_DDC_Insights Practical workflows: n8n automation, AI agents, field tools 20 You need workflow automation
4_DDC_Curated Document generation (PDF, Excel, DOCX, PPTX), quality checks 20 You need document or report templates
5_DDC_Innovative Advanced: computer vision, IoT, digital twins, risk assessment 29 You're ready for AI/ML experimentation
mindmap
  root((DDC Skills<br/>221 skills))
    1_DDC_Toolkit
      CWICR Database
        55,719 work items
        31 languages
      CAD Converters
        RVT → Excel
        IFC → Excel
        DWG → Excel
      Analytics
        KPI Dashboard
        Cost Analysis
    2_DDC_Book
      Part I: Data Evolution
      Part II: Data Types
      Part III: Estimation
      Part IV: Analytics & ML
      Part V: Threats & Strategy
    3_DDC_Insights
      n8n Workflows
        Daily Reports
        Photo Reports
      AI Agents 2026
      Field Automation
    4_DDC_Curated
      Document Generation
        PDF, Excel
        DOCX, PPTX
      Quality Assurance
    5_DDC_Innovative
      AI/ML Skills
        Defect Detection
        Risk Assessment
      IoT & Sensors
      Advanced BIM
        Digital Twin

Where to Start

If you manage or lead a construction company:

Step 1. Read GETTING_STARTED.md — a non-technical overview of what can be automated and how to prioritize.

Step 2. Download the Data-Driven Construction book (free, 31 languages) — it explains the methodology behind these skills: how to assess your company's data maturity, identify bottlenecks, and plan digital transformation.

Step 3. Identify your biggest pain point in the table below and start with the corresponding skill.

If you are a developer or IT lead:

Step 1. Install prerequisites (see Prerequisites).

Step 2. Pick a skill from the table below, open its folder in your AI assistant, and follow the SKILL.md.

Step 3. Adapt the generated code to your data and deploy.


What Can You Automate?

Examples of common problems and which skills address them:

Your problem What the skill does Skill to run Folder
Searching for work item rates takes too long Semantic search across 55,719 items in 31 languages semantic-search-cwicr 1_DDC_Toolkit/
Estimators spend days building estimates manually Generates estimates from historical data and templates estimate-builder 1_DDC_Toolkit/
BIM models contain data but it's locked in RVT/IFC files Extracts quantities and properties to Excel ifc-to-excel, rvt-to-excel 1_DDC_Toolkit/
Daily/weekly reports take hours to compile Automated data collection and report generation n8n-daily-report 3_DDC_Insights/
Site photos pile up with no organization AI classifies and tags site photos automatically n8n-photo-report 3_DDC_Insights/
Data is scattered across Excel files, emails, PDFs Finds all data sources and maps dependencies data-silo-detection 2_DDC_Book/
No visibility into project KPIs Dashboard with real-time metrics from your data kpi-dashboard 1_DDC_Toolkit/
Budget overruns discovered too late Scheduled budget vs. actual comparison budget-tracker 1_DDC_Toolkit/
PDF specifications need to be searchable Extracts text and tables from PDFs into structured data specification-extractor 2_DDC_Book/
Schedule delays are hard to predict Statistical analysis of schedule variance patterns schedule-delay-analyzer 3_DDC_Insights/

This is a selection of examples. The full collection contains 221 skills covering estimation, reporting, BIM, document processing, analytics, and more.


How to Use a Skill

1. Clone this repository
   git clone https://github.com/datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction.git

2. Open a skill folder in your AI assistant
   cd DDC_Skills_for_AI_Agents_in_Construction/1_DDC_Toolkit/CWICR-Database/semantic-search-cwicr/

3. The assistant reads SKILL.md and generates the code for you

4. Review, adapt to your data, and run

Example: ETL Pipeline

# Automatic processing of all Excel files from a folder

import pandas as pd
from pathlib import Path

# Extract
all_data = [pd.read_excel(f) for f in Path("./estimates/").glob("*.xlsx")]
df = pd.concat(all_data)

# Transform
df['Total'] = df['Quantity'] * df['Unit_Price']
summary = df.groupby('Category')['Total'].sum()

# Load
summary.to_excel("summary_report.xlsx")

Implementation Path

A typical automation project follows these stages. You don't need to do all of them — start with what solves your most pressing problem.

Stage What you do Which skills help
1. Audit List all data sources in your company (Excel files, databases, BIM models, PDFs, emails) data-silo-detection, data-source-audit
2. Classify Understand what data you have: structured, semi-structured, or unstructured data-type-classifier, data-profiler
3. Connect Build ETL pipelines to extract and normalize data etl-pipeline, ifc-to-excel, specification-extractor
4. Automate Set up recurring reports, alerts, and dashboards n8n-daily-report, kpi-dashboard, budget-tracker
5. Analyze Apply analytics and ML to find patterns and predict outcomes cost-prediction, schedule-forecaster, risk-assessment

Each stage builds on the previous one, but you can enter at any point depending on your current state.


How Does It Work?

Each step in the implementation path corresponds to specific skills and tools:

flowchart LR
    subgraph S1["STEP 1"]
        A[Audit<br/>Find Data Silos]
    end

    subgraph S2["STEP 2"]
        B[Classify<br/>Data Types]
    end

    subgraph S3["STEP 3"]
        C[Connect<br/>ETL Pipelines]
    end

    subgraph S4["STEP 4"]
        D[Automate<br/>Reports & Dashboards]
    end

    subgraph S5["STEP 5"]
        E[Analyze<br/>ML & Predictions]
    end

    A --> B --> C --> D --> E

    A1[data-silo-detection<br/>data-source-audit] -.-> A
    B1[data-type-classifier<br/>data-profiler] -.-> B
    C1[etl-pipeline<br/>ifc-to-excel] -.-> C
    D1[n8n-daily-report<br/>kpi-dashboard] -.-> D
    E1[cost-prediction<br/>schedule-forecaster] -.-> E

    style S1 fill:#ffebee
    style S2 fill:#fff3e0
    style S3 fill:#e8f5e9
    style S4 fill:#e3f2fd
    style S5 fill:#f3e5f5

Data Types in Construction

Construction data comes in three forms. Each requires a different processing approach, and each has corresponding skills:

flowchart TB
    subgraph STRUCTURED["STRUCTURED"]
        S1[Excel]
        S2[SQL Database]
        S3[CSV]
    end

    subgraph SEMI["SEMI-STRUCTURED"]
        M1[IFC/BIM]
        M2[JSON]
        M3[XML]
    end

    subgraph UNSTRUCTURED["UNSTRUCTURED"]
        U1[PDF]
        U2[Photos]
        U3[Scans]
    end

    STRUCTURED -->|SQL queries, pandas| DB[(Central<br/>Database)]
    SEMI -->|ifcopenshell, parsers| DB
    UNSTRUCTURED -->|AI/OCR, pdfplumber| DB

    DB --> AUTO[Automation & Analytics]

    style STRUCTURED fill:#c8e6c9
    style SEMI fill:#fff9c4
    style UNSTRUCTURED fill:#ffcdd2
    style DB fill:#e1f5fe
    style AUTO fill:#f3e5f5
Data type Examples Skills that process it
Structured Excel, CSV, SQL databases etl-pipeline, estimate-builder, budget-tracker
Semi-structured IFC/BIM models, JSON, XML ifc-to-excel, rvt-to-excel, dwg-to-excel
Unstructured PDF documents, photos, scans specification-extractor, n8n-photo-report, document-ocr

Prerequisites

Requirement Details
Python 3.9+ Most skills use Python scripts
AI Coding Assistant Claude Code, Cursor, Copilot, or similar
Basic Python knowledge Ability to run scripts and install packages
Your data Excel files, PDFs, or BIM models to process

Optional for advanced skills:
- Docker (for n8n workflows)
- PostgreSQL or SQLite (for database skills)
- OpenAI API key (for LLM-based skills)

Installation

pip install pandas openpyxl ifcopenshell pdfplumber

Data Flow in Construction

Skills cover the typical data pipeline: from raw input files to processed, actionable outputs.

flowchart LR
    subgraph INPUT["📥 YOUR DATA"]
        A1[Excel Estimates]
        A2[Revit/IFC Models]
        A3[Site Photos]
        A4[PDF Documents]
    end

    subgraph DDC["⚙️ DDC SKILLS"]
        B1[ETL Pipeline]
        B2[IFC Parser]
        B3[AI Analysis]
        B4[Document OCR]
    end

    subgraph OUTPUT["📤 RESULTS"]
        C1[Auto Reports]
        C2[Auto Estimates]
        C3[Progress Tracking]
        C4[Searchable Data]
    end

    A1 --> B1 --> C1
    A2 --> B2 --> C2
    A3 --> B3 --> C3
    A4 --> B4 --> C4

    style INPUT fill:#e1f5fe
    style DDC fill:#fff3e0
    style OUTPUT fill:#e8f5e9

Construction data comes in three forms. Each requires a different processing approach:

Data type Examples How skills process it
Structured Excel, CSV, SQL databases Direct queries and transformations
Semi-structured IFC/BIM models, JSON, XML Parsing with specialized libraries
Unstructured PDF documents, photos, scans AI/OCR extraction to structured format

Folder Structure

DDC_Skills/
│
├── 1_DDC_Toolkit/              ← Production tools (85 skills)
│   ├── CWICR-Database/         ← 55,719 work items database
│   ├── CAD-Converters/         ← Revit/IFC/DWG → Excel
│   └── ...
│
├── 2_DDC_Book/                 ← Skills from the book (67 skills)
│   ├── 1.1-Data-Evolution/     ← Digital maturity assessment
│   ├── 1.2-Data-Silos-Integration/  ← Find & connect data sources
│   ├── 3.1-Cost-Estimation/    ← Build estimates from data
│   ├── 4.2-ETL-Automation/     ← Automate data pipelines
│   └── ...
│
├── 3_DDC_Insights/             ← Practical workflows (20 skills)
│   ├── Automation-Workflows/   ← n8n automation
│   ├── AI-Agents/              ← Multi-agent systems (2026)
│   ├── Field-Automation/       ← Telegram bot, voice reports
│   └── Open-Data-Transparency/ ← Uberization readiness
│
├── 4_DDC_Curated/              ← External skills (20 skills)
│   ├── Document-Generation/    ← PDF/Excel/DOCX/PPTX generation
│   └── Quality-Assurance/      ← Quality checks
│
├── 5_DDC_Innovative/           ← Advanced AI/ML skills (29 skills)
│   ├── defect-detection-ai/    ← Computer vision for defects
│   ├── digital-twin-sync/      ← Real-time BIM sync
│   └── ...
│
├── Books/                      ← Free book downloads (31 languages)
├── GETTING_STARTED.md          ← START HERE
└── README.md                   ← You are here

Documentation

Document Description Audience
GETTING_STARTED.md Step-by-step automation guide Executives, beginners
OPTIMIZER_GUIDE.md How to work effectively with AI assistants Developers
IMPROVEMENT_ROADMAP.md Collection development plan Contributors

Potential Time Savings

Automation results vary depending on company size, data quality, and implementation effort:

Process Manual approach With automation
Find work item rate Search through price books Database query with filters
Daily report compilation Collect data from multiple sources Pre-configured data aggregation
IFC quantity extraction Open model, measure manually Script-based extraction to Excel
Budget variance tracking Weekly spreadsheet updates Scheduled comparison reports
Document organization Manual folder sorting Metadata-based classification

Results depend on data preparation and workflow complexity. See GETTING_STARTED.md for implementation guidance.


About the Book

The majority of skills are based on the book "Data-Driven Construction" — a methodology for digital transformation in construction. The book explains the reasoning behind each skill category: why data silos matter, how to classify your data, and what to automate first.

Data-Driven Construction Book **Book structure maps to skills:** 1. **Part I** — Data landscape assessment → `2_DDC_Book/1.1-*`, `1.2-*` 2. **Part II** — Data types and classification → `2_DDC_Book/2.1-*` through `2.6-*` 3. **Part III** — Estimation and scheduling → `2_DDC_Book/3.1-*` through `3.3-*` 4. **Part IV** — Analytics and ML → `2_DDC_Book/4.1-*` through `4.5-*` 5. **Part V** — Threats and long-term strategy → `2_DDC_Book/5.*` **[Download Free in 31 Languages →](Books/)**

Resources

Resource Link
Book (All Languages) https://datadrivenconstruction.io/books/
Website https://datadrivenconstruction.io
CWICR Demo https://openconstructionestimate.com
GitHub https://github.com/datadrivenconstruction
CWICR Database https://github.com/datadrivenconstruction/OpenConstructionEstimate-DDC-CWICR
CAD2Data Pipeline https://github.com/datadrivenconstruction/cad2data-Revit-IFC-DWG-DGN-pipeline-with-conversion-validation-qto

Support the Project

If you find these tools useful, please give the repository a star — it helps others discover these resources.

GitHub stars

Related repositories:

Repository Description
OpenConstructionEstimate-DDC-CWICR 55,719 work items database in 31 languages
cad2data Pipeline Revit/IFC/DWG/DGN to Excel converter

Contributing

Contributions are welcome:
- Report issues — bugs, unclear documentation, broken links
- Suggest skills — describe the automation you need
- Submit PRs — new skills, improvements, translations

Each skill should include a SKILL.md with clear instructions and working code examples.


License

  • CWICR Database: CC BY 4.0
  • DDC Tools: MIT License
  • Skills: MIT License

Trademarks

All product names, logos, and brands mentioned in this repository are property of their respective owners. All company, product and service names used are for identification purposes only. Use of these names, logos, and brands does not imply endorsement.

  • IFC is an open standard by buildingSMART International
  • File format references (RVT, DWG, DGN, NWD, etc.) are used for technical interoperability purposes only

Start here → GETTING_STARTED.md

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.