Paste this prompt into the OpenCode TUI to let your AI agent walk you through this lesson:
What is D1?
D1 is Cloudflare’s serverless SQL database. Under the hood, it’s SQLite — you get full SQL support, but it runs at the edge alongside your Worker. There’s no connection string, no VPN, no cold start penalty. Your Worker accesses D1 through a binding, which means it’s available as env.INCIDENTS_DB in your code with zero network hops.
Why D1 here? The incident queue needs structured data: incident IDs, titles, severity levels, timestamps, alert types, and raw telemetry payloads. D1 gives you a real SQL database for this without any infrastructure management.
D1 data flow: Worker to incident queue
flowchart LR W[Worker] -->|env.INCIDENTS_DB| D1[(D1 Database)] D1 --> T[incidents table] T --> id[incident_id] T --> src[source] T --> title[title] T --> sev[severity] T --> ts[received_at] T --> tel[raw_payload] D1 -->|SQL query| W W -->|JSON response| UI[UI Incident Queue]
Step 0: Navigate to the lesson-06-d1 directory
From your current lesson-05-empty directory, move to the lesson 06 directory:
cd ..\lesson-06-d1
Step 1: Create the D1 database
Run the following command to create a new D1 database:
npx wrangler d1 create sirt-incidents
The output will include a database_id — copy that value. It looks like this:
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Step 2: Replace the database ID in wrangler.jsonc
Open lesson-06-d1\wrangler.jsonc in your editor. The D1 binding is already configured — you just need to replace the placeholder with your actual database ID.
Find this line:
"database_id": "REPLACE_WITH_YOUR_DATABASE_ID"
Replace REPLACE_WITH_YOUR_DATABASE_ID with the database_id you copied in Step 1:
"database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Step 3: Run the seed migration
The workshop app includes a pre-written migration file at migrations\001-seed.sql. This file creates an incidents table and inserts ten sample incidents.
Run the migration against your remote D1 database:
npx wrangler d1 execute sirt-incidents --remote --file=migrations\001-seed.sql
The --remote flag is important — it runs the migration on your deployed D1 database, not a local copy.
You should see output confirming the SQL was executed successfully.
The ten seeded incidents span a range of security scenarios:
- Malware + C2 Beacon — Encoded PowerShell, C2 IP communication
- Phishing + BEC — Credential harvesting, mailbox forwarding rule
- Anomalous Authentication — Impossible travel, MFA bypass via legacy protocol
- Data Exfiltration — Off-hours upload to personal cloud storage
- AI Prompt Injection — Attempt to extract system prompt from internal AI assistant
- CSPM Cloud Misconfiguration — S3 bucket changed to public access
- Credential Stuffing — Rotating-IP brute force against login endpoint
- User-Reported Phishing — Suspicious invoice email with .zip attachment
- Compromised CI Pipeline — Unauthorized npm package from CI runner
- Ransomware Encryption — Mass file encryption on file server
Step 4: Install dependencies and deploy
Install the lesson dependencies and deploy:
npm install
npm run deploy
Now reload your app in the browser. Instead of the “Incident Queue” placeholder, you should see ten incident cards in the queue, each showing:
- The incident title
- The severity level (P0, P1, P2)
- The alert source
- The timestamp
Click on an incident to see its detail view. At this stage, the detail view shows raw telemetry data but no analysis — that comes in later lessons when you add Workers AI and the agent harness.