From Paperwork Mountains to Digital Freedom: Building an IDP Solution with Kiro

Published: (January 6, 2026 at 09:58 AM EST)
6 min read
Source: Dev.to

Source: Dev.to

Challenge: Office Staff Drowning in Paperwork

Every morning, Mai arrives at the government office where she works. Her desk is already piled high with paper documents – citizen applications, official reports, meeting minutes, and forms that need to be digitized.

Like thousands of office workers, Mai faces an exhausting daily routine:

  • 💢 Type for hours: Manually transcribing each document into Word
  • 💢 Hunt for errors: Reviewing for typos and formatting mistakes
  • 😫 Work overtime: Staying late to finish the backlog
  • 😫 Feel exhausted: Repeating the same tedious task every single day

A single 5‑page official document takes 30‑45 minutes to transcribe. With dozens arriving daily, Mai is overwhelmed.

What if there was a better way?

The Idea

I wanted to build a solution where office staff could:

  1. Take photos with their smartphone camera
  2. Wait ~30 seconds while AI processes them
  3. Download perfectly formatted Word documents
  4. Done! Ready to review and distribute

But I had a problem: I didn’t know where to start.

  • How do I use AWS Bedrock for OCR?
  • How do I create properly formatted Word documents?
  • How do I preserve Vietnamese document headers?
  • How do I build a web interface?
  • How do I deploy on AWS?

That’s when I turned to Kiro — my AI coding assistant.

Kiro to the Rescue

First Prompt

Me: "Given the AWS Bedrock Converse API and Claude Sonnet 4, build an AI solution to OCR images from a folder and convert them to Word DOCX files. Prefer Python. Search the internet for references."

Kiro’s output (within minutes):

  • Fetched AWS Bedrock Converse API documentation
  • Researched python-docx library
  • Created a complete project structure
  • Generated working code

The first version worked, but Vietnamese official documents have a special two‑column header that wasn’t captured correctly.

Handling Two‑Column Headers

My request:

“The phrase ‘CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM’ should be in a table with two columns. Left column has organization info, right column has the country header and date.”

Kiro’s response:

  • Updated the OCR prompt to detect two‑column headers
  • Modified create_docx.py to parse structured markup
  • Created borderless tables for proper formatting
  • Tested the changes automatically

Structured OCR Prompt

STRUCTURED_OCR_PROMPT = """
For Vietnamese official document headers with two columns, output as:
[HEADER_TABLE]
[LEFT]
organization line 1
organization line 2
Số: xx /TB-xxx
[/LEFT]
[RIGHT]
CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM
Độc lập - Tự do - Hạnh phúc  
Tp. xxx, ngày xx tháng xx năm xxxx
[/RIGHT]
[/HEADER_TABLE]
"""

Result: Perfect two‑column headers!

Grouping Multi‑Page Documents

I wanted images with similar names (e.g., doc-1.png, doc-2.png) to be combined into one Word file (doc.docx).

My request:

“If images have names with the same prefix but different numbers after a hyphen (e.g. tb-1, tb-2), group them into one DOCX file (e.g. named tb) with multiple pages.”

Kiro’s implementation:

def get_prefix_and_page(filename: str) -> tuple:
    """
    Extract prefix and page number from filename.
    Examples:
        'invoice-1.png' -> ('invoice', 1)
        'report_2.jpg'   -> ('report', 2)
        'standalone.png' -> ('standalone', 0)
    """
    stem = Path(filename).stem
    match = re.match(r'^(.+?)[-_](\d+)$', stem)

    if match:
        return match.group(1), int(match.group(2))
    return stem, 0

Result: Automatic multi‑page document creation!

Building a User‑Friendly Web Interface

The CLI worked, but I needed a modern web UI.

My request:

“Deploy a website that accepts image uploads, stores them in an S3 bucket, processes with Bedrock, outputs DOCX files, and provides download links.”

Kiro’s response (within minutes):

  • Complete Flask web application
  • Drag‑&‑drop upload interface
  • S3 integration for storage
  • Session management for multi‑user support
  • Download functionality with presigned URLs
  • HTML templates

Example Flask Route

@app.route('/upload', methods=['POST'])
def upload_files():
    """Handle file upload and processing"""
    files = request.files.getlist('files')
    session_id = str(uuid.uuid4())[:8]

    # Upload to S3
    for file in files:
        filename = secure_filename(file.filename)
        local_path = f"/tmp/{filename}"
        file.save(local_path)

        s3_key = f"images/{session_id}/{filename}"
        s3_client.upload_file(local_path, S3_BUCKET, s3_key)

        # OCR with Bedrock
        text = ocr_image_with_bedrock(local_path)
        ocr_results[filename] = text

    # Create grouped DOCX files
    create_grouped_documents(ocr_results)

    return jsonify({"status": "processing started"})

The first UI worked but looked basic. I wanted something modern.

My request:

“The dashboard icons and colors look unacceptable. Search for modern color schemes and upgrade the UI.”

Kiro’s makeover:

  • Dark theme with purple/blue gradients
  • Glassmorphism effects on cards
  • Animated background patterns
  • Mobile‑responsive design
  • Success animations for feedback

Modern Design System (CSS)

/* Kiro's modern design system */
:root {
    --primary:   #6366f1;
    --secondary: #0ea5e9;
    --accent:    #8b5cf6;
    --gradient: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #0ea5e9 100%);
}

Result: Beautiful, professional interface!

Final Demo

You can upload two image files following the naming convention (e.g., tb-1.png, tb-2.png) and click Convert to DOCX.
Processing takes about 1 minute.

Demo video: https://haianh-sing.s3.ap-southeast-1.amazonaws.com/2026-01-06+21-56-16.mp4

After just 1 hour with Kiro, we had a complete, production‑ready Intelligent Document Processing platform that would have taken days to build manually.

Feature Summary

FeatureDescription
AI‑Powered OCRClaude Sonnet 4 with 95 %+ accuracy
Mobile‑FirstWorks with any smartphone camera
Vietnamese SupportPreserves official document formatting
Multi‑PageAutomatic grouping by filename
Web InterfaceBeautiful, responsive dark‑theme design
Cloud‑NativeAWS S3, Bedrock, EC2 Graviton (ARM64)
SecureIAM roles with least‑privilege access
Cost‑Effective≈ $0.003 per page
Production‑ReadyDeployed to AWS with monitoring

AWS Account Setup

  • AWS Account with Bedrock access in us‑west‑2 (or any region that supports Bedrock)
  • Required IAM permissions: bedrock:*, s3:* (restricted to your bucket), ec2:* for the instance, and CloudWatch for monitoring.

Enable Claude Sonnet 4 Model in Bedrock Console

Prerequisites

  • IAM user with admin access (for initial setup)
  • Local development environment
    • Python 3.9 or higher
    • AWS CLI (configured with aws configure)
    • Git

Step 1 – Create IAM Role

# Create role with trust policy
aws iam create-role \
    --role-name Image2Docx-EC2-Role \
    --assume-role-policy-document file://iam-trust-policy.json

# Attach permissions policy
aws iam put-role-policy \
    --role-name Image2Docx-EC2-Role \
    --policy-name Image2Docx-Policy \
    --policy-document file://iam-policy.json

# Create instance profile
aws iam create-instance-profile \
    --instance-profile-name Image2Docx-EC2-Profile

# Add role to profile
aws iam add-role-to-instance-profile \
    --instance-profile-name Image2Docx-EC2-Profile \
    --role-name Image2Docx-EC2-Role

Step 2 – Launch EC2 Instance

# Launch Graviton (ARM64) instance – cost‑efficient
aws ec2 run-instances \
    --image-id ami-xxxxxxxxx \   # Amazon Linux 2023 ARM64
    --instance-type t4g.micro \
    --key-name your-key-pair \
    --security-group-ids sg-xxxxxxxxx \
    --iam-instance-profile Name=Image2Docx-EC2-Profile \
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=Image2Docx-Server}]'

Step 3 – Configure Security Group

# Allow inbound HTTP on port 8080
aws ec2 authorize-security-group-ingress \
    --group-id sg-xxxxxxxxx \
    --protocol tcp \
    --port 8080 \
    --cidr 0.0.0.0/0

# Allow SSH for administration (replace with your IP)
aws ec2 authorize-security-group-ingress \
    --group-id sg-xxxxxxxxx \
    --protocol tcp \
    --port 22 \
    --cidr /32

Step 4 – Deploy the Application

# SSH into the instance
ssh -i "your-key.pem" ec2-user@<public-ip>

# Update the system
sudo yum update -y

# Install dependencies
sudo yum install -y git python3-pip

# Clone the repository
git clone https://github.com/PNg-HA/Image2Docx.git
cd Image2Docx

# Install Python packages
pip3 install -r requirements.txt

# Run the app in the background
nohup python3 app.py > app.log 2>&1 &

Step 5 – Access Your Application

Open a browser and navigate to:

http://<public-ip>:8080

Success! Your intelligent documentation platform is live.

Why This Matters

We started with a simple question: “Can we help office staff escape the paperwork trap?”
The answer is a resounding YES—and the journey is just as remarkable as the result.

This platform is my contribution to eliminating paperwork drudgery and freeing office workers. More importantly, it demonstrates that anyone with vision and AI assistance can build transformative solutions.

What will you build with Kiro?

Back to Blog

Related posts

Read more »

Rapg: TUI-based Secret Manager

We've all been there. You join a new project, and the first thing you hear is: > 'Check the pinned message in Slack for the .env file.' Or you have several .env...

Technology is an Enabler, not a Saviour

Why clarity of thinking matters more than the tools you use Technology is often treated as a magic switch—flip it on, and everything improves. New software, pl...