# AI Projects through Prompting

Example Projects done through prompting only in Codex, Gemini CLI, v0 or OpenCode

# Project Overview

### 🗺️ Curriculum Roadmap

The bootcamp is structured into 10 weekly milestones, focusing on full-stack development and AI integration.

* **Week 01: Personal Dashboard**
  * **Project:** Personal Dashboard
  * **Goal:** Build a link organizer with a database for a custom browser "new tab" page.
* **Week 02: Build an App with Live Data**
  * **Project:** Events Dashboard
  * **Goal:** Live data visualization using APIs and charts.
* **Week 03: Build an App with Users**
  * **Project:** Shared Expense Tracker
  * **Goal:** Implementing User Authentication (Sign up/Log in) and data ownership.
* **Week 04: Build a Real-Time App**
  * **Project:** Live Chat Room
  * **Goal:** Create interfaces that update live without refreshing.
* **Week 05: Build an AI-Powered App**
  * **Project:** Ingredient Combiner
  * **Goal:** Integrate AI capabilities into your own application.
* **Week 06: Build a CLI Tool**
  * **Project:** Site Inspector CLI
  * **Goal:** Build a terminal tool that inspects any website.
* **Week 07: Build a Paid Product**
  * **Project:** Premium Version of a Previous App
  * **Goal:** Turn your app into a business with real payments.
* **Week 08: Build an Online Store**
  * **Project:** Small-Batch Product Shop
  * **Goal:** Create a complete e-commerce experience with cart and checkout.
* **Week 09: Build an App with AI Agents**
  * **Project:** Link Sharing Community with AI Bots
  * **Goal:** Create AI bots that interact with your app autonomously.
* **Week 10: Build a Complete Product**
  * **Project:** Newsletter Tool
  * **Goal:** Combine everything into one polished, ship-ready application.

---

### 🌐 Resources & Community

* **Platform:** [Bootcamp Dashboard](https://bootcamp.dev/login)
* **Community:** Discord (Private Invite Required)
* **Support:** Access to a peer network for troubleshooting and building in public.

---

### 📂 Technical Constraints Note

> **Internal Note:** The student has identified a mismatch between the course content (Cloud/API heavy) and their professional environment (Air-gapped/Offline systems). This Wiki entry serves as a record of the curriculum prior to the refund request on **March 8, 2026**.

# 🚀 Week 01: The Personal Dashboard

### "Your Digital Command Center"

Welcome to the first real project. In the first week, we aren't just coding; we are reclaiming your browser. Instead of a cluttered "New Tab" page, you’re building a lightning-fast, minimalist link organizer that lives on your machine.

<span style="white-space: pre-wrap;">The goal for this milestone is to master </span>**CRUD**<span style="white-space: pre-wrap;"> (Create, Read, Update, Delete) operations and understand how a frontend interface talks to a local database.</span>

---

### 🛠️ Phase 1: The Foundation

<span style="white-space: pre-wrap;">Before you paste your prompt into an AI, you need to decide on your </span>**Tech Stack**. A good tech-stack is one that lets you ship the fastest, but here are some recommended paths:

<table id="bkmrk-stackwhy-choose-it%3Fn"><colgroup><col style="width: 194px;"></col><col></col></colgroup><tbody><tr><th>Stack

</th><th>Why choose it?

</th></tr><tr><td>**Next.js + Tailwind + SQLite**

</td><td>The modern industry standard. Fast, sleek, and everything stays in one folder.

</td></tr><tr><td>**Python (Flask) + Bootstrap + TinyDB**

</td><td>Great if you prefer a lighter, more logic-focused backend approach.

</td></tr><tr><td>**Deno + Typescript + HTMX + AlpineJS**

</td><td>Great if you prefer a lightweight stack with simple components that lets you create a single executable binary with the help of demo.

</td></tr><tr><td>**Astro + HTMX + AlpineJS**

</td><td>The AHA-Stack. Simple, minimal and effective.

</td></tr></tbody></table>

> **Action Item:**<span style="white-space: pre-wrap;"> Decide on your language. Do you want to go the JavaScript/TypeScript route or the Python route?</span>

---

### 🤖 The Master Prompt

Once you've picked your stack, use this comprehensive prompt to generate the "v1.0" of your dashboard:

```text
Build me a personal link dashboard that I'll use as my browser's new tab page.
[INSERT CHOSEN STACK HERE: e.g., Using Next.js and SQLite]

The app organizes links into categories. Each category has a name and contains multiple links. 
Each link has a name and a URL.

Features I need:
- Display links grouped by category in a clean grid/card layout.
- Add a new link (with name, URL, and category selection).
- Edit and Delete existing links.
- Create and delete entire categories.
- Store everything in a local database (setup instructions included).
- Run on localhost.

Design: Make it clean, dark-mode friendly, and minimal. It must load instantly.
```

---

### 🛠️ Phase 2: Iteration Prompts

Use the next prompts to enhacne your dashboard with more features. Often is less more and small iterations make it easier to get better results.

When you enable git you can also always go back and undo changes.

Also the Planing-Mode in many agents can help to layout a plan before doing any major tasks.

#### 1. Real-Time Fuzzy Search &amp; Filtering

```text
Implement a global search bar at the top of the dashboard.
As the user types, it should filter the displayed
categories and links in real-time. Use fuzzy-matching
logic so searching for 'git' matches 'GitHub' or
'GitLab'. If a category has no matching links, hide the
entire category heading from the view to keep the UI clean.
```

#### 2. Dynamic Favicon &amp; Metadata Fetching

```text
Enhance the link display by adding a 16x16px favicon next
to each link name. Generate the icon URL dynamically
using: https://www.google.com/s2/favicons?domain=[URL]&sz=32
Add a fallback 'Earth' icon using your icon library if the
favicon fails to load, ensuring the layout remains
consistent and aligned.
```

#### 3. Persistent Dark Mode &amp; System Preference

```text
Add a theme toggle component (Sun/Moon icon). The system
should check for the user's OS preference using
'prefers-color-scheme' on first visit but allow manual
override. Store the chosen theme in localStorage. Apply
a 'dark' class to the root HTML element and ensure all
CSS transitions for colors are smooth (300ms duration).
```

#### 4. Drag-and-Drop Reordering (Persistent)

```text
Integrate a drag-and-drop library (like dnd-kit) to allow
reordering of links within a category. When a link is
dropped, send a PATCH request to the backend to update a
'sort_order' integer field in the database. Ensure the UI
updates optimistically so there is no visual lag while
the database saves the new order.
```

#### 5. Data Portability: JSON Backup &amp; Restore

```text
Create a 'System' modal that allows data management.
Include an 'Export' button that generates and downloads
a 'dashboard_backup.json' file containing all data.
Also, include a file upload input for 'Import' that
parses the JSON file, validates the schema, and performs
a bulk-insert into the database to restore the setup.
```

#### 6. Smart URL Validation &amp; Auto-Naming

```text
Improve the 'Add New Link' form. When a user pastes a URL,
use a regex to validate it. If valid, use a client-side
fetch or server-side route to attempt to scrape the
<title> tag of that website. Automatically populate the
'Link Name' field with this title, allowing the user to
edit it before saving.
```

#### 7. Keyboard Navigation &amp; "Quick Actions"

```text
Implement global 'Hotkeys' for power users. Pressing '/'
should instantly focus the search bar; pressing 'n'
should open the 'Add New Link' modal; and pressing 'Esc'
should close any open modals. Add a small footer or
tooltip that visually reminds the user of these
shortcuts to improve discoverability.
```

---

### 💡 Implementation Tip

<span style="white-space: pre-wrap;">When using these, I recommend pasting the </span>**relevant file code**<span style="white-space: pre-wrap;"> (e.g., your </span>`<span class="editor-theme-code">page.tsx</span>`<span style="white-space: pre-wrap;"> or </span>`<span class="editor-theme-code">api/links.js</span>`) along with the prompt. This prevents the AI from hallucinating variable names that don't exist in your project.

# 📊 Week 02: The Centralized Event Hub

<span style="white-space: pre-wrap;">Welcome to </span>**Week 02**<span style="white-space: pre-wrap;">! You’ve already knocked out your personal dashboard; now we’re stepping into the world of </span>**Dynamic Orchestration**. This week, you aren't just building a display—you are building the "Nervous System" for every application you will ever write.

## 📡 The Mission: Observation &amp; Architecture

<span style="white-space: pre-wrap;">The goal is to build a </span>**Centralized Event Dashboard**<span style="white-space: pre-wrap;">. This application acts as a private "Log Sink" or "Command Center." It provides a secure API that listens for "Events" from your other apps—whether it’s a successful user signup from a web app, a cron job failure in a Python script, or a simple </span>`<span class="editor-theme-code">cURL</span>`<span style="white-space: pre-wrap;"> message from your terminal.</span>

Build a two-part system:

1. **The Receiver (Remote API):**<span style="white-space: pre-wrap;"> A cloud-hosted endpoint that is "always on," waiting to catch events from your other apps, scripts, or servers.</span>
2. **The Viewer (Local Dashboard):**<span style="white-space: pre-wrap;"> A high-performance real-time feed where you can search, filter, and visualize the data flowing through your API.</span>

### 🛠️ The Architecture

- **Project-Based Isolation:**<span style="white-space: pre-wrap;"> Manage multiple apps from one hub.</span>
- **API Key Authentication:**<span style="white-space: pre-wrap;"> Secure your endpoints so only your authorized apps can post data.</span>
- **Persistent Cloud Storage:**<span style="white-space: pre-wrap;"> Use a cloud database so your data is safe and accessible even when your local machine is off.</span>

---

## 🚀 Step 0: Choose Your Stack

<span style="white-space: pre-wrap;">Before you run your first prompt, decide on your </span>**Tech Stack**. You will need a database (like Supabase or PostgreSQL) to store your projects and historical event data.

<table id="bkmrk-componentoption-a%3A-m" style="font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-line: none; text-decoration-thickness: auto; text-decoration-style: solid; animation: auto; appearance: none; background: 0% 0% repeat rgba(0, 0, 0, 0); border: 0px rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 32px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; outline: rgb(31, 31, 31) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; x: 0px; y: 0px; zoom: 1;"><colgroup><col></col><col></col><col></col></colgroup><tbody><tr style="animation: auto; appearance: none; background: 0% 0% repeat rgba(0, 0, 0, 0); border: 0px rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1;"><td style="background: 0% 0% repeat rgb(239, 239, 239); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**Component**

</td><td style="background: 0% 0% repeat rgb(239, 239, 239); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**Option A: Modern Serverless (Recommended)**

</td><td style="background: 0% 0% repeat rgb(239, 239, 239); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**Option B: Robust Python**

</td></tr><tr style="animation: auto; appearance: none; background: 0% 0% repeat rgba(0, 0, 0, 0); border: 0px rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1;"><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**Backend API**

</td><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;"><span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">Next.js API Routes (Vercel) or Hono (Cloudflare)</span>

</td><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;"><span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">FastAPI (Render or Railway)</span>

</td></tr><tr style="height: 10px; animation: auto; appearance: none; background: 0% 0% repeat rgba(0, 0, 0, 0); border: 0px rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1;"><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**Database**

</td><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**Supabase**<span style="white-space: pre-wrap;"> </span><span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">(PostgreSQL + Realtime)</span>

</td><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**MongoDB Atlas**<span style="white-space: pre-wrap;"> </span><span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">or Supabase</span>

</td></tr><tr style="animation: auto; appearance: none; background: 0% 0% repeat rgba(0, 0, 0, 0); border: 0px rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1;"><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**Frontend**

</td><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;"><span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">Next.js + Tailwind + Shadcn UI</span>

</td><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;"><span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">React (Vite) + Tailwind</span>

</td></tr><tr style="animation: auto; appearance: none; background: 0% 0% repeat rgba(0, 0, 0, 0); border: 0px rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1;"><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;">**Live Updates**

</td><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 12px 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;"><span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">Native Supabase Realtime</span>

</td><td style="background: 0% 0% repeat rgba(0, 0, 0, 0); animation: auto; appearance: none; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); column-width: auto; column-count: auto; contain: none; container-name: none; container-type: normal; content: normal; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; isolation: auto; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; mask-size: auto; mask-composite: add; mask-mode: match-source; offset-path: none; offset-distance: 0px; offset-position: normal; offset-anchor: auto; offset-rotate: auto; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) 0px; padding: 16px 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; border: 1px solid;"><span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">Pusher or Socket.io</span>

</td></tr></tbody></table>

> **Student Note:**<span style="white-space: pre-wrap;"> Are you a </span>**Next.js + Tailwind**<span style="white-space: pre-wrap;"> fan? Or do you prefer </span>**Python (FastAPI) + React**? Specify this in your initial prompt so the AI builds the API routes correctly.

---

## 🚀 The Starter Prompt

Copy and paste this into your AI chat to generate the foundation.

```text
Build me an events dashboard. Other applications send events to it through an API, and I see them in a real-time feed.

The app has two parts:
1. A REST API that accepts events via POST request (with API key authentication). This needs to run on a remote server so it's always available, even when my computer is off.
2. A dashboard that displays events in a feed, with search, filtering, and charts. This can run locally.

Each event has: a channel (category like "orders", "signups", "deploys"), a title, an optional description, an optional emoji icon, and optional tags.

Features I need:
- POST /api/events endpoint that accepts JSON and stores events in the database
- API key authentication (generate a key when creating a project)
- A feed page showing events in reverse chronological order
- Filter events by channel
- Search events by title, description, or tags
- At least one chart showing event activity over time
- The dashboard should update in real-time when new events arrive
- Use a cloud database that's always available (Supabase, Convex, or similar)

Make it clean and functional. I want to actually use this to monitor my own projects.

Before making any decisions on the stack. Make a stack proposal and ask me which I want to use.
```

Once you have the initial dashboard frontend, api and database running to your liking, you can continue with the next prompts, to make it better or add additional features to it.

## 📈 Evolution: 7 Prompts to Pro Power

Once your API can catch a message, use these iterative prompts to turn a "basic table" into a professional monitoring tool.

## The Roadmap:

- **The Real-Time Subscription:**<span style="white-space: pre-wrap;"> Implement a real-time listener (e.g., Supabase Realtime) to push new events to the feed instantly with a highlight animation.</span>
- **Smart Emoji &amp; Auto-Parsing:**<span style="white-space: pre-wrap;"> Add logic to automatically assign emojis based on channel names (e.g., 💰 for orders, 🚀 for deploys) if one isn't provided.</span>
- **Multi-Project Management:**<span style="white-space: pre-wrap;"> Build a settings page to manage multiple projects, each with its own name and unique API key validation.</span>
- **Advanced Time-Series Analytics:**<span style="white-space: pre-wrap;"> Integrate Recharts to visualize events per hour and top channels using bar and pie charts across various time ranges.</span>
- **Desktop &amp; Critical Alerts:**<span style="white-space: pre-wrap;"> Add native browser notifications triggered by specific tags like #error or #urgent, even when the dashboard is in the background.</span>
- **The "Deep Dive" Inspector:**<span style="white-space: pre-wrap;"> Create a clickable side-drawer for every event to display the raw JSON payload and include a "Copy as cURL" button for debugging.</span>
- **Key Rotation &amp; Security:**<span style="white-space: pre-wrap;"> Implement a security feature to regenerate API keys, instantly voiding old credentials to protect against leaks.</span>

---

### 🛠️ The Detailed Prompt List

1. <span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">The Real-Time Subscription</span>

> <span style="white-space: pre-wrap;">"Since our database is in the cloud, implement a </span>**Real-time Listener**<span style="white-space: pre-wrap;"> (e.g., Supabase Realtime). Ensure that when the remote API inserts a new event, the local dashboard pushes it to the top of the feed automatically with a subtle 'new item' highlight animation."</span>

2. <span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">Smart Emoji &amp; Channel Parsing</span>

> <span style="white-space: pre-wrap;">"Enhance the API logic: if an incoming event doesn't specify an emoji icon, automatically assign one based on the </span>`<span class="editor-theme-code">channel</span>`<span style="white-space: pre-wrap;"> name (e.g., 'orders' gets 💰, 'deploys' gets 🚀, 'errors' gets ❌). Display these icons prominently next to the event title in the feed."</span>

3. <span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">Multi-Project API Key Management</span>

> "Build a 'Project Settings' page in the dashboard. Allow me to create multiple projects, each with its own name and unique generated API key. The API should now validate the key against the database and tag the incoming event to the correct project automatically."

4. <span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">Advanced Time-Series Analytics</span>

> <span style="white-space: pre-wrap;">"Add a 'Metrics' tab. Use </span>**Recharts**<span style="white-space: pre-wrap;"> to create a bar chart showing 'Events per Hour' and a pie chart showing 'Top Channels by Volume.' Allow me to toggle the time range between the last 24 hours, 7 days, or 30 days."</span>

5. <span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">Desktop &amp; Push Notifications</span>

> "Add a toggle in the dashboard for 'Critical Alerts.' If an event is received with a specific tag (like #error or #urgent) or a 'High' priority status, trigger a browser-native desktop notification so I see the alert even if the dashboard tab is hidden."

6. <span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">The "Deep Dive" JSON Inspector</span>

> "Make each event card clickable. When clicked, open a side-drawer (Slide-over) that shows the full raw JSON payload received by the API formatted for readability. Include a 'Copy as cURL' button so I can easily replicate the exact request for debugging."

7. <span style="color: rgb(31, 31, 31); background-color: rgba(0, 0, 0, 0);">API Key Security &amp; Rotation</span>

> "Implement 'Key Rotation' logic. In the Project Settings, add a button to 'Regenerate API Key.' This should instantly void the old key in the database and provide a new 32-character secret to the user, ensuring security if a key is ever accidentally leaked."

###   

# Best Practices for Working with AI Agents: A Verification-Driven Approach

<span style="white-space: pre-wrap;">Working effectively with AI agents requires a fundamental shift in how we approach development. While AI can generate vast amounts of code instantly, the primary challenge is no longer authorship, but </span>**verification**<span style="white-space: pre-wrap;">. Modern software engineering with AI is less about crafting the "perfect prompt" and more about maintaining a </span>**disciplined, step-by-step process**.

Here is a comprehensive guide on how to optimally interact with AI agents, supported by real-world examples.

### 1. The Mindset Shift: Engineering Over Prompting

<span style="white-space: pre-wrap;">In the AI era, your core value shifts from typing speed to three essential competencies: </span>**Problem Definition, Decomposition, and Verification**.

- **You are the Architect, AI is the Typist:**<span style="white-space: pre-wrap;"> You are entirely responsible for the logic, security, and data flow.</span>
- **Avoid the "One-Shot Trap":**<span style="white-space: pre-wrap;"> A common beginner mistake is the "5-second high"—asking the AI to generate a complete application from a single sentence. This creates a massive </span>**technical debt of understanding**. If you cannot verify the output, you do not own the code, making it a liability rather than an asset.

### 2. Precise vs. Imprecise: The Power of Constraints

<span style="white-space: pre-wrap;">Your prompts must be </span>**highly precise when it comes to rules, constraints, and edge cases**. Ambiguity is the enemy of secure AI-generated code.

- **Example: The Server-Side Cart Calculator**<span style="white-space: pre-wrap;"> If you simply ask an AI to "build a shopping cart," you risk getting vulnerable client-side logic where a user could manipulate prices. Instead, you must define a strict trust boundary where the server is the single source of truth. A precise prompt establishes rigid constraints:</span>
    - **Ignore Client Prices:**<span style="white-space: pre-wrap;"> Explicitly state to never accept a price sent from the browser.</span>
    - **Validation Constraints:**<span style="white-space: pre-wrap;"> Define mathematical rules, such as $Quantity \\ge 1$ and $Tax/Discount \\ge 0$.</span>
    - **Order of Operations:**<span style="white-space: pre-wrap;"> Mandate that discounts must be applied </span>**before**<span style="white-space: pre-wrap;"> calculating tax.</span>
    - **Precision:**<span style="white-space: pre-wrap;"> Require the system to round money to 2 decimal places (or use integers/cents to avoid floating-point errors).</span>

### 3. Short vs. Long Prompts: The Iterative Workflow

<span style="white-space: pre-wrap;">Instead of writing one massive prompt, the most effective strategy is </span>**iterative prompting**. Start with a structured, medium-length prompt to define the goal and constraints, then transition to short, highly focused commands to build and refine the output incrementally.

- **Example: Rapid UI Iteration via Short Prompts**<span style="white-space: pre-wrap;"> During the development of a real-time events dashboard, a developer used extremely short prompts to polish the UI once the foundational context was established by the AI.</span>
    - <span style="white-space: pre-wrap;">The developer prompted: </span>**"make the bar chart smaller and horizontal. different colors for channels. randomly assigned."**.
    - Because the AI already understood the established architecture, this short prompt was enough for the agent to formulate a highly detailed implementation plan—creating a compact horizontal layout and using a deterministic hash-to-color function so that channels kept a stable pseudo-random color across page reloads.
    - <span style="white-space: pre-wrap;">The developer then followed up with rapid micro-prompts like </span>**"increase font contrast of labels of bar chart"**<span style="white-space: pre-wrap;"> and </span>**"the colors of the background and the overlays do not match the dark"**. The AI executed these perfectly by tuning CSS overlay tokens and applying theme-aware colors.

### 4. The 7-Step Verification Loop: Trust but Verify

<span style="white-space: pre-wrap;">Never assume the agent's first output is flawless. You must </span>**treat AI-generated code like code from a stranger—useful, but untrusted until proven by tests**. Fundamentals matter more than ever: security, data flow, and edge-case thinking are your primary tools.

<span style="white-space: pre-wrap;">To ensure quality and maintain control, adopt this repeatable </span>**7-Step Iterative Loop**:

1. **Define the Goal:**<span style="white-space: pre-wrap;"> State the objective in one clear sentence.</span>
2. **Establish Rules:**<span style="white-space: pre-wrap;"> List the non-negotiable technical constraints (what </span>**must**<span style="white-space: pre-wrap;"> be true).</span>
3. **Provide Examples:**<span style="white-space: pre-wrap;"> Define the exact expected Input $\\rightarrow$ Output mappings.</span>
4. **Identify Edge Cases:**<span style="white-space: pre-wrap;"> List "weird" or bad situations the system needs to handle.</span>
5. **Request a "Small Piece":**<span style="white-space: pre-wrap;"> Ask for a specific function or logic gate, not the whole system.</span>
6. **Demand Tests:**<span style="white-space: pre-wrap;"> Require the AI to provide runnable assertions to prove its logic.</span>
7. **Iterate:**<span style="white-space: pre-wrap;"> Treat failing tests as data. Use them as a "flashlight" to refine your next prompt and fix ambiguities in your rules.</span>

- **Example: Actively Verifying System Logic**<span style="white-space: pre-wrap;"> Verification isn't just about automated tests; it's also about actively questioning the AI's architectural decisions. When the AI added data filters to a dashboard's charts, the developer didn't just accept the code. They verified the logic by asking: </span>**"how do the filters work? do they filter visible data or data on the server?"**<span style="white-space: pre-wrap;">. Only after the AI confirmed that the filters were applied securely on the server side via SQL query parameters, did the developer instruct the AI to solidify this architecture: </span>**"document the changes do you?"**, ensuring the verified logic was permanently recorded in the project's README.