DDactic Blog / Engineering
Engineering · February 2026 · 10 min read

363,000 Lines of Code in 60 Days: Building a Cybersecurity SaaS With AI

One engineer. Fifteen years of DDoS testing experience. An AI coding assistant. In roughly 60 working days, we shipped a production cybersecurity SaaS platform spanning 8 programming languages, 19 cloud providers, and 2,441 files. This is an honest account of what worked, what didn't, and why the interesting part isn't the AI.

The Numbers

Let me start with the raw output, because the numbers are what made me write this post. I went back through the git history and counted.

363K
Lines of Code
2,441
Files
8
Languages
13
Cloud Platforms
~60
Working Days
1
Human Engineer

The language breakdown: Go for infrastructure and deployment (the multi-cloud engine, bot binary, Fleet Controller), Python for the backend API (Flask on a dedicated server), TypeScript for Cloudflare Workers functions, C for a raw TCP scanner, HTML/CSS/JS for the frontend, PowerShell and Bash for automation scripts. Not toy projects -- production code handling real traffic, real money, real customer data.

To be clear: I'm not claiming I typed 363,000 lines. Much of this was generated by Claude (Anthropic's AI assistant), which I used as my primary development tool. But "generated" is doing a lot of heavy lifting in that sentence, and the distinction between generated and authored is where the interesting story lives.

What I Built

DDactic is a DDoS resilience testing platform. Companies hire us to stress-test their infrastructure before attackers do. The platform needed to do several things that most SaaS products don't:

The architecture looks like this:

/* Request flow */

Cloudflare Pages (sales/)
    |
Cloudflare Workers (sales/functions/api/)   // 40+ endpoints
    |
Dedibox Backend (Python Flask)              // api.ddactic.net
    |
    +--> AWS Batch                         // Recon scanning jobs
    +--> Go Deploy Service                 // Multi-cloud orchestration
    +--> Fleet Controllers (Go, behind ALB)  // Bot fleet coordination
           |
           Bot Fleet                         // 19 cloud platforms

Every layer of this stack was built in those 60 days. Frontend, backend, infrastructure, tooling, deployment automation, billing, documentation. From zero to a platform that actual customers use.

Where AI Excelled

I want to be specific here, because vague claims about "AI productivity" are useless. Here are the concrete categories where Claude dramatically accelerated my work.

Boilerplate With Domain Context

The single biggest time savings was in code that follows established patterns but requires domain-specific knowledge to get right. Cloud platform adapters are the perfect example. After I built the first two (AWS and Hetzner) by hand, I could describe what I needed for adapter #3 through #19, and Claude would produce correct implementations on the first or second attempt.

Each adapter needs to handle authentication, instance creation, status polling, destruction, error mapping, and region enumeration -- but every cloud API does these differently. The pattern is the same; the details are completely different. This is exactly the kind of work that's tedious for a human but trivial for an LLM that has seen every cloud SDK.

// Every platform implements this interface.
// The pattern is identical. The implementation is wildly different.
type PlatformAdapter interface {
    Deploy(config *BotDeploymentConfig) ([]UnifiedInstance, error)
    Destroy(filter DestroyFilter) (int, error)
    Status() ([]UnifiedInstance, error)
    Regions() []string
}

// UnifiedInstance normalizes across all 19 platforms.
type UnifiedInstance struct {
    ID           string    `json:"id"`
    Platform     string    `json:"platform"`
    Region       string    `json:"region"`
    InstanceType string    `json:"instance_type"`
    Status       string    `json:"status"`
    IP           string    `json:"ip"`
    CreatedAt    time.Time `json:"created_at"`
    Spot         bool      `json:"spot"`
}

I described the Vultr API's quirks (synchronous creation, no native spot support, API key auth via header). Claude produced a working adapter in minutes. For IBM -- which requires pre-provisioning VPC infrastructure before you can create an instance -- I explained the dependency chain, and it handled the multi-step provisioning correctly.

Cross-Language Consistency

When your platform spans 8 languages, keeping data contracts consistent is a real problem. I'd define a scan result schema in the Go scanner, and need the Python backend to parse it, the TypeScript worker to forward it, and the JavaScript frontend to render it. Claude maintained these contracts across languages with near-perfect consistency, because it could hold the entire schema in context.

This is something that would take a human engineer constant cross-referencing and inevitable drift. The AI just... remembered the struct definition from 3 files ago and produced matching code in a different language.

The 80% First Draft

For most features, Claude produced an 80% correct first draft. The Cloudflare Workers auth system (OAuth with GitHub and Google, session management, MFA) was functional on the first pass. The billing calculator that aggregates costs across 19 cloud providers was structurally correct. The SSE streaming endpoint for real-time scan progress worked immediately.

That remaining 20% is where all the interesting engineering happens. But getting to 80% in minutes instead of hours changes what a single person can build in a day.

Documentation and Tests

I'll admit this freely: I would not have written comprehensive documentation or extensive test cases for a solo project under time pressure. Claude generated both. Not because I asked it to be thorough, but because it tends to produce documentation alongside code. The result is a codebase that's actually navigable by someone other than me -- which matters when you're trying to grow a company.

Where AI Failed

This section is more important than the previous one. Understanding where AI breaks down tells you something real about the technology. Understanding where it succeeds mostly tells you things you already suspected.

Platform Quirks and Undocumented Behavior

Cloud providers have behaviors that aren't in any documentation. Claude couldn't know them because nobody has written them down. These cost me days, not hours.

OVH and AWS share the same metadata IP address (169.254.169.254). When our boot script runs on an OVH instance, a naive platform detection check says "this is AWS." We had to add a pre-check for /openstack/latest/vendor_data.json -- a path that exists on OVH's OpenStack but not on AWS. Claude didn't know this. Nobody writes blog posts about OVH metadata quirks.

More examples that cost real debugging time:

The pattern is clear: AI is excellent when problems are well-documented. It fails when the answer exists only in the operational experience of people who've run into the same wall.

Distributed Systems Debugging

When 200 bot instances across 19 clouds are supposed to register with a Fleet Controller and 40 of them don't show up, the debugging process is fundamentally different from fixing a function that returns the wrong value. You're correlating logs across systems that don't share a timezone, dealing with network partitions that are intermittent, and reasoning about race conditions that only manifest under load.

Claude could help me write log analysis scripts. It could suggest potential causes. But it couldn't do the actual debugging -- the part where you SSH into a Hetzner instance in Singapore, check the systemd journal, notice the DNS resolution is failing because the instance came up before the network interface was ready, and add a 5-second sleep to the boot script. That kind of reasoning requires seeing the full state of the system, and no LLM can do that today.

Architecture Decisions

This is the subtlest failure mode. Claude would happily build whatever I described, even when the architecture was wrong. It never pushed back and said "you should use WebSockets instead of SSE polling here" or "this billing calculation will have floating-point rounding issues at scale." It built what I asked for, correctly, and the architectural problems only emerged later.

For example: I initially had the Cloudflare Workers calling cloud provider APIs directly. Claude implemented this faithfully. It worked in development. It failed in production because Vultr, DigitalOcean, and Hetzner all block Cloudflare Workers IP ranges. We had to add an entire proxy layer through the Dedibox backend. Claude wrote the proxy layer too, but it never flagged the original architecture as problematic.

The lesson: AI is a tool that amplifies your judgment. If your judgment is wrong, it amplifies that too, and it does it faster than you can course-correct.

The Metadata Endpoint Problem (A Case Study)

This one crystallizes the AI failure mode perfectly. Our bot binary needs to detect which cloud platform it's running on, using metadata endpoints. Here's the detection order:

// Platform detection: 19 clouds, 7 metadata IPs,
// and an endless parade of edge cases.

169.254.42.42      --> Scaleway
100.100.100.200    --> Alibaba
169.254.0.23       --> Tencent
169.254.169.254    --> AWS? GCP? Azure? OVH? Oracle?
                      (5 platforms share this IP)

// Differentiation for 169.254.169.254:
Metadata-Flavor: Google  --> GCP
/metadata/instance       --> Azure
/openstack/vendor_data   --> OVH  (check BEFORE AWS)
/opc/v2/instance         --> Oracle
/latest/meta-data        --> AWS  (last resort for this IP)

// Fallbacks for platforms without unique metadata IPs:
/sys/class/dmi/id/sys_vendor  --> "Akamai" = Linode
                                --> "Vultr" = Vultr
hostname -f                   --> contains "-ibm-" = IBM

Claude's first implementation checked AWS before OVH. It worked on AWS. It broke on every OVH instance. Because both respond at 169.254.169.254, and the AWS metadata path returns data on OVH too (it's OpenStack under the hood). The check order matters, and getting it right required knowing how OVH's infrastructure actually works -- knowledge that doesn't exist in training data.

Oh, and every single metadata curl call needs --connect-timeout 3 --max-time 5. Without those flags, a curl to a non-existent metadata IP hangs forever. The initial implementation didn't have timeouts. Every bot instance that tried to detect the wrong platform first would hang for minutes. Claude didn't add timeouts because the documentation examples don't include them. The documentation assumes you're running on the right platform.

The Real Lesson

Here's what I keep coming back to: the bottleneck was never typing code.

Before AI, the bottleneck for this project wouldn't have been implementation speed. It would have been calendar time -- the sheer number of days needed to write, test, and debug code across 8 languages and 19 platforms. A team of 3-4 engineers could have built this in 60 days. A solo engineer couldn't, because there aren't enough hours.

AI collapsed the implementation time. But it didn't collapse the thinking time. Every architectural decision -- how the fleet coordination protocol should work, why we chose HTTP/2 over WebSockets for bot communication, how to handle cross-cloud identity without a shared key store, why the boot script self-updates before doing anything else -- came from 3 years of building and breaking DDoS infrastructure at a leading Israeli DDoS simulation company.

The formulation that feels right: AI turns domain expertise into working software at roughly the speed you can describe what you want. The description is the bottleneck now, and the quality of the description depends entirely on the depth of your expertise.

An engineer with no DDoS experience could not have built this platform with AI in any amount of time. Not because the AI can't write the code, but because they wouldn't know what code to write. They wouldn't know that you need to check OVH metadata before AWS. They wouldn't know that Cloudflare Workers can't call Cloudflare Tunnels (loopback protection). They wouldn't know that spot instance recovery needs to redeploy as spot, not on-demand, or your costs balloon.

Domain expertise is the moat. It always was. AI just made the moat more visible by eliminating everything else.

What This Means for Solo Founders

I think there's a window right now -- maybe 2-3 years -- where solo technical founders with deep domain expertise have an unprecedented advantage. Here's why:

But I want to be honest about the limitations. This approach works because I'm building in a domain where I have deep hands-on experience. If I tried to build a machine learning pipeline or a financial trading system with AI, I'd produce something that looks correct and is subtly, dangerously wrong. The AI would happily implement my misconceptions at scale.

The solo founder advantage isn't "AI writes code." It's "AI writes code for people who know exactly what code needs to be written."


Appendix: Technical Deep Dive

For readers who want specifics, here are the technical details behind the numbers.

The Deploy Service

A single Go binary (cmd/deploy-service/main.go) running on a dedicated server. Three HTTP endpoints: POST /deploy, POST /destroy, GET /status. Each of 19 cloud platforms has a dedicated adapter in pkg/deploy/. A deploy request looks like this:

{
    "platform": "hetzner",
    "count": 10,
    "instance_type": "cpx11",
    "regions": ["ash", "hil", "sin"],
    "spot": true,
    "c2c_server": "c2c.ddactic.net"
}

The service generates platform-specific userdata (cloud-init scripts), distributes instances across requested regions, creates instances via the platform API, and returns a list of UnifiedInstance objects. Average time from API call to running bot: ~15 seconds for most platforms, ~45 seconds for IBM (VPC provisioning overhead).

The Boot Sequence

Every bot instance, on every platform, runs the same boot.sh on startup. The script has evolved through 9 major versions, driven primarily by platform-specific failures that only surface in production:

# boot.sh v9 - the version that actually works everywhere

# Phase 0: Self-update (catches the "stale boot script" problem)
curl -sf http://binary-server:9999/boot.sh -o /tmp/boot_new.sh
if ! diff -q /tmp/boot_new.sh /opt/ddactic/boot.sh; then
    cp /tmp/boot_new.sh /opt/ddactic/boot.sh
    exec /opt/ddactic/boot.sh  # re-execute updated version
fi

# Phase 1: Platform detection (order matters!)
# Check Scaleway first (unique IP: 169.254.42.42)
# Check Alibaba second (unique IP: 100.100.100.200)
# Check OVH BEFORE AWS (both use 169.254.169.254)
# ...

# Phase 2: Generate BOT_ID from instance metadata
# Phase 3: Download latest binary (18MB, with retry)
for i in 1 2 3 4 5; do
    curl --connect-timeout 10 --max-time 120 \
         -o /opt/ddactic/bot http://binary-server:9999/bot_latest \
    && break
    sleep $((i * 5))
done

The Recon Pipeline

Three-stage reconnaissance running on AWS Batch, each stage built as a separate Go binary:

StageToolFunction
1. Discoveryrecon_company-domainsSLD enumeration, subdomain discovery, DNS records, ASN mapping, cloud provider identification
2. Port Scanrecon_domains-portsGlobalPing multi-region probing, Nmap, last-hop detection, CDN filtering (--skip-cdn)
3. L7 Reconrecon_http, recon_dns, recon_smtp, recon_sipuTLS fingerprinting, DNSSEC analysis, SMTP security, SIP probing

Stage 1 results stream to S3 as they're discovered. The scanner binary uses short-form flags (-c not --company) because -- and this is the kind of thing that wastes hours -- AWS Batch's argument parsing chokes on long flags with equals signs in certain configurations. We found this at 2 AM.

The Physical Device Lab

For application-layer traffic analysis, we run actual hardware: a jailbroken iPhone 7 Plus (iOS 14.3) and a Lenovo Yoga tablet (Android 10). A Python service intercepts traffic, extracts API endpoints, TLS fingerprints, and protocol behaviors. 44 Windows desktop applications are captured via a remote Windows Server lab.

This is the part AI was least helpful with. Traffic interception on jailbroken iOS requires knowledge of Frida, SSL kill switches, and iOS internals that's too niche for an LLM to get right without extensive back-and-forth. I wrote most of the interception code by hand.

The Residential Proxy

Certificate Transparency logs (crt.sh) are a key data source for subdomain discovery, but crt.sh aggressively rate-limits datacenter IPs. Our solution: a Go proxy running on a residential ISP connection, exposed to our backend via Cloudflare Tunnel. The backend pre-fetches subdomain data through the residential IP before spawning AWS Batch jobs.

Cloudflare Workers cannot call Cloudflare Tunnel endpoints directly (loopback protection). We route through the Dedibox backend as an intermediary. This is the kind of architectural constraint that AI doesn't flag because it's specific to Cloudflare's internal networking, not a general programming concept.


Final Thought

A year ago, I would have looked at the requirements for this platform and estimated 6 months with a 4-person team. Instead, it took 60 days with one person and an AI.

That's a real shift. But the reason it worked isn't the AI. It's that I'd spent years accumulating the knowledge of what to build, and the AI gave me a way to build it at the speed I could think. The thinking was always the hard part. It still is.

If you're a domain expert considering whether AI-assisted development can let you build something ambitious solo -- yes, it probably can. But only if you already know, deeply, what you're building. The AI writes the code. You have to be the architect.

DDactic is a DDoS resilience testing platform. If you're interested in our engineering approach or want to discuss AI-assisted development, reach out at [email protected].