About the Project

What Inspired Us

Every organization has them—legacy applications gathering dust in forgotten repositories. Systems that once powered critical operations, now abandoned because the technology is obsolete, the original developers are gone, or the documentation has vanished. The traditional answer? Start from scratch and spend months (or years) rebuilding.

We asked a different question: What if we could extract the business logic from dead code and bring it back to life in modern technologies?

For this Kiroween experiment, we chose three real legacy hospital management applications:

  • A hospital admin system
  • An appointment manager
  • A blood pressure reporting tool

Three different applications. Three incompatible architectures. Three systems that would traditionally require months of reverse engineering and rewriting. We gave ourselves 4 days.

What We Learned

1. Business Logic is Technology-Agnostic

The most valuable insight: business logic doesn't care about the technology it's written in. A validation rule, a workflow, a calculation—these are pure logic that can be extracted and reimplemented anywhere.

Using rhino.ai, we discovered that even poorly documented legacy code contains structured, extractable knowledge. The AI analyzed codebases, identified patterns, and produced clear business logic documents that became our source of truth.

2. Specifications Enable Parallel Development

Traditional development bottlenecks disappeared when we worked from formal specifications. Three developers in different time zones collaborated seamlessly because:

  • Requirements were unambiguous
  • Design decisions were documented
  • Task boundaries were clear
  • Integration points were defined upfront

No meetings to clarify requirements. No merge conflicts from overlapping work. No "wait, what were we building again?"

3. Property-Based Testing Preserves Logic

When migrating legacy systems, the biggest fear is: "Did we lose something?"

We used property-based testing to encode business rules as mathematical properties:

  • If a patient registers, they must have a unique ID
  • If an appointment is scheduled, the time slot must be available
  • If blood pressure is recorded, it must be within valid ranges

These properties ran hundreds of test cases automatically, giving us confidence that the new system preserved the old system's correctness.

4. AI Amplifies, Doesn't Replace

rhino.ai and Kiro didn't write the code for us—they amplified our capabilities:

  • rhino.ai extracted logic we would have spent weeks reverse-engineering
  • Kiro maintained context and consistency across a complex codebase
  • We made architectural decisions, wrote implementations, and verified correctness

The result was $\text{human expertise} \times \text{AI assistance} = \text{exponential productivity}$

How We Built It

Day 1: Extraction & Specification (Monday)

Morning: Archaeological Discovery

  • Fed three legacy codebases into rhino.ai
  • Provided documentation fragments, user manuals, and screenshots
  • Let the AI analyze patterns, workflows, and business rules

Afternoon: Logic Resurrection

  • Reviewed rhino.ai's extracted business logic
  • Created formal specifications in Kiro
  • Defined requirements, design, and implementation tasks
  • Split work into three parallel tracks

End of Day: Blueprint Complete

  • Full specifications ready for implementation
  • Clear task assignments for each developer
  • Shared understanding of the unified system

Day 2-3: Implementation (Tuesday-Wednesday)

Backend Development (Developer 1)

  • SQLAlchemy models for unified data schema
  • Alembic migrations for database versioning
  • Repository pattern for data access
  • Property-based tests for business logic

API Development (Developer 2)

  • FastAPI endpoints with automatic documentation
  • JWT authentication and role-based authorization
  • Service layer for business logic
  • Integration tests for cross-module functionality

Frontend Development (Developer 3)

  • React components with TypeScript
  • Custom hooks for state management
  • Responsive UI with modern CSS
  • Form validation and error handling

Continuous Verification Throughout:

# Every commit was tested
pytest backend/tests/
npm test --run

Day 4: Integration & Deployment (Thursday)

Morning: Final Integration

  • Connected all three legacy system functionalities
  • End-to-end testing across modules
  • UI/UX refinements based on original systems

Afternoon: Production Deployment

  • Docker containerization
  • PostgreSQL database setup
  • Environment configuration
  • Deployment to cloud infrastructure

Result: Production-ready application by end of day

Challenges We Faced

Challenge 1: Reconciling Incompatible Data Models

The Problem: Three legacy systems had overlapping but inconsistent data models. The admin system had "Staff," the appointment system had "Doctors," and the blood pressure system had "Providers."

The Solution: We created a unified User model with role-based differentiation:

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    role = Column(Enum('admin', 'doctor', 'receptionist', 'patient'))
    # Unified fields from all three systems

This preserved the functionality of all three systems while eliminating redundancy.

Challenge 2: Lost Business Rules

The Problem: Some validation rules existed only in the UI layer of legacy apps, with no documentation.

The Solution: We used rhino.ai to analyze UI code and extract implicit business rules. For example, discovering that appointment slots were 30 minutes and couldn't overlap—a rule never explicitly documented but enforced in the old JavaScript.

Challenge 3: Time Zone Coordination

The Problem: Three developers across different time zones meant limited overlap for synchronous communication.

The Solution: Specifications became our async communication layer. Each developer could:

  • Read specs to understand requirements
  • Implement their assigned tasks independently
  • Commit with references to task numbers
  • Trust that integration would work because interfaces were pre-defined

Challenge 4: Preserving Domain Knowledge

The Problem: Legacy systems contained years of domain knowledge—edge cases, workarounds, business rules learned through real-world use.

The Solution: Property-based testing encoded this knowledge as invariants:

@given(st.text(min_size=1))
def test_patient_name_never_empty(name):
    # Business rule: patient names must exist
    assert validate_patient_name(name) is not None

These tests ran hundreds of scenarios, catching edge cases the original developers had handled.

Challenge 5: Balancing Speed and Quality

The Problem: 4 days is aggressive. How do we move fast without breaking things?

The Solution: Specification-driven development with continuous verification:

  1. Write clear specs (prevents rework)
  2. Implement incrementally (small, testable units)
  3. Test continuously (catch issues immediately)
  4. Commit frequently (always have a working state)

The formula: $\text{speed} = \frac{\text{clarity} \times \text{automation}}{\text{rework}}$

By maximizing clarity (specs) and automation (tests) while minimizing rework (continuous verification), we achieved both speed and quality.

Technical Architecture

Backend: FastAPI + PostgreSQL

  • Why FastAPI? Modern, fast, automatic API documentation
  • Why PostgreSQL? ACID compliance, robust for healthcare data
  • Pattern: Repository → Service → Router (clean separation of concerns)

Frontend: React + TypeScript

  • Why React? Component reusability across three legacy UIs
  • Why TypeScript? Type safety prevents runtime errors
  • Pattern: Custom hooks for business logic, presentational components for UI

Infrastructure: Docker + Docker Compose

  • Why Docker? Consistent environments, easy deployment
  • Why Compose? Multi-container orchestration (app + database)
  • Pattern: Automated migrations, environment-based configuration

The Numbers

  • 3 legacy applications
  • 3 developers
  • 4 days (Monday-Thursday, 9-5)
  • 0 overtime hours
  • 7-11 months saved vs traditional approach
  • 100% business logic preservation
  • value unlocked from "dead" code

What's Next

This project proves that legacy modernization doesn't have to be a multi-year death march. With the right tools and approach, trapped value can be freed in days, not months.

For this application:

  • HIPAA compliance for production healthcare use
  • Mobile app for patient access
  • Integration with existing hospital systems
  • Advanced analytics and reporting

For the approach:

  • Apply to other industries (finance, retail, manufacturing)
  • Build a library of common legacy patterns
  • Create automated migration pipelines
  • Share the methodology with the community

Try It Yourself

The entire codebase, specifications, and documentation are open source. See for yourself how three legacy systems became one modern application in 4 days.

Live Demo: Frontend

Repository: GitHub


Built with rhino.ai, Kiro, and a belief that legacy code deserves a second life. 🧪⚡

Share this project:

Updates