Course Overview

Courses 1–5 taught you to build tools on Power Platform — low-code applications within the Microsoft ecosystem. That’s powerful, and most Marines will never need more.

But some problems don’t fit inside Power Apps. When you need a custom AI chat interface, role-based dashboards with real-time data, or an application that deploys anywhere from a laptop to Azure Government — you need full-stack development.

This course teaches you to build that. Not by learning to code from scratch, but by learning to direct AI to write code for you, verify it works, and iterate when it doesn’t. The same Cyborg pattern from Course 3, applied at a fundamentally higher level.

What You’ll Build

By the end of this course, you will have built and deployed a working web application with:

  • A Go backend serving a REST API with multiple endpoints
  • A React frontend with multiple pages, navigation, and interactive features
  • A data layer that reads from JSON files (upgradeable to SQLite or PostgreSQL)
  • An AI chat interface that queries your application’s data through tool use
  • Role-based authentication so different users see different data
  • A Docker container deployed to Azure Container Apps (or running locally)

This is exactly how Heywood TBS was built.

Six Principles of AI-Assisted Full-Stack Development

  1. The Conversation is the IDE. Your AI chat window is your primary development tool. Code editors are for verification, not authoring. You tell the AI what you need; it writes the code.
  2. Scaffold → Flesh Out → Integrate. Always start with the skeleton. Get a blank page loading before adding features. Get one API endpoint working before building ten. Never try to build everything at once.
  3. The 3-Minute Rule. If the AI’s output doesn’t work after 3 minutes of debugging, paste the exact error message back to the AI. Don’t manually debug AI-generated code — let the AI fix its own work.
  4. Incremental Deployment. Deploy after every major feature, not at the end. If you wait until the end to deploy, you’ll spend hours debugging environment issues instead of building features.
  5. Interface-First Design. Define what your system needs to do before how it does it. Tell the AI “I need a function that takes a student ID and returns their record” — not “write me a SQL query.” AI excels at implementing well-defined interfaces.
  6. Copy the Error, Not Your Frustration. When something breaks, give the AI the exact error message and the file that caused it. Don’t say “it doesn’t work” — say “I get this error when I run go build.”

Instructor Requirements

This course requires an instructor who has:

  • Built and deployed at least one full-stack web application using AI assistance
  • Experience with Go or another backend language (Python, Node.js can substitute)
  • A working Docker installation on the instructor machine
  • An Azure subscription (or ability to demo deployment)
  • An OpenAI API key or Azure OpenAI access

Critical: The instructor should build the entire application themselves before teaching this course, following the student prompts. You need to know where students will get stuck, because they will.

Agenda & Timing

Time Module What Students Build Key Skill
0:00–0:30 1. The Full-Stack Frontier Mental model shift Understanding scope
0:30–1:15 2. Environment Setup Go, Node, Git, VS Code, Docker installed AI-guided installation
1:15–2:00 3. Backend from Scratch Go HTTP server, router, first endpoint AI-generated server code
2:00–2:45 4. Data Layer DataStore interface, JSON store, seed data Interface-first design
2:45–3:00 Break (15 minutes)
3:00–3:45 5. Frontend from Scratch React + Vite + TypeScript, first page AI-assisted frontend
3:45–4:30 6. Pages & Navigation Dashboard, detail page, sidebar, routing Iterative UI building
4:30–5:15 7. AI Chat Integration Chat page, OpenAI API, tool use Building AI into your app
5:15–5:30 Break (15 minutes)
5:30–6:15 8. Auth & Middleware Role-based auth, protected routes Security patterns
6:15–7:00 9. External Integrations Database or Microsoft Graph API Connecting real services
7:00–7:45 10. Docker & Deployment Containerized app on Azure Local to production
7:45–8:00 Wrap-Up & Assessment Deployed app + frontier map Self-assessment
Total Course Time 8 hours (480 minutes)

Pacing Note

This is an aggressive pace. Some students will fall behind, especially in Modules 3–4 (backend) and Module 7 (AI chat). That’s expected. The instructor should:

  • Have a pre-built “checkpoint” version of the app at each module boundary
  • Students who fall behind can clone the checkpoint and continue from there
  • Prioritize: if time is short, skip Module 9 (External Integrations) — it’s the most independent module

Module 1: The Full-Stack Frontier

Duration: 30 minutes

This module shifts students’ mental model from “I build Power Apps” to “I can build anything.” The goal isn’t to make them software engineers — it’s to make them realize that AI has moved the frontier so far that the distinction between “coder” and “non-coder” is dissolving.

1.1 The Before and After

Start with a live demo. Open the Heywood TBS application and show:

  • The Dashboard — 200 students, real-time analytics, at-risk identification
  • The Chat — ask “Morning brief” and watch it pull live data
  • The Settings page — database connections, Outlook integration, admin config
  • The role picker — switch from XO to Student, watch the entire UI adapt

Then reveal:

Key Reveal

“This application has 8,400 lines of Go backend code, 4,400 lines of React frontend code, 35 API endpoints, 5 database backends, Microsoft Graph integration, CAC authentication, and FIPS 140-3 compliance. It was built in days, not months, by one person working with AI. No team of contractors. No six-month timeline. No $2M budget.”

1.2 Why Full-Stack?

Walk through the limitations students have hit with Power Platform:

Limitation Power Platform Full-Stack
Custom AI chat interface Not possible (Copilot Studio is limited) Build exactly what you need
Role-based dashboards Power BI RLS (complex setup) Code it directly — one app, four views
Offline / disconnected ops Requires internet + M365 license Docker container runs anywhere
Data sovereignty Data lives in Microsoft cloud Data stays where you put it
Cost per user $20+/user/month (Power Apps license) $0 — open source, self-hosted
Deployment flexibility Microsoft cloud only Azure, AWS, on-prem, laptop, ship, field

1.3 The Stack We’re Building

Draw this on the whiteboard (or show the slide):

Application Architecture
┌─────────────────────────────────────┐
│          React Frontend              │
│   (What the user sees and clicks)    │
├─────────────────────────────────────┤
│          Go HTTP Server              │
│   (Handles requests, returns data)   │
├─────────────────────────────────────┤
│          Data Layer                  │
│   (Stores and retrieves data)        │
├─────────────────────────────────────┤
│          External Services           │
│   (AI APIs, Outlook, databases)      │
└─────────────────────────────────────┘

Explain each layer in one sentence:

  • Frontend — React code that runs in the user’s browser. It draws the screens and sends requests to the backend.
  • Backend — Go code that runs on the server. It receives requests, processes data, and sends back JSON.
  • Data Layer — Where the data lives. Starts as JSON files, can upgrade to SQLite or PostgreSQL.
  • External Services — Other systems your app talks to: OpenAI for chat, Microsoft Graph for Outlook, etc.

1.4 How AI Changes Everything

In traditional development, a junior developer spends years learning a programming language before building anything useful. With AI-assisted development:

  • You describe what you want in plain English
  • The AI writes the code
  • You verify it works (run it, check the output)
  • If it doesn’t work, you paste the error back and the AI fixes it
  • Repeat until done

You don’t need to understand every line of code. You need to understand:

  1. What to ask for (requirements — you learned this in Courses 1–4)
  2. How to verify it works (run the code, check the browser)
  3. How to debug failures (paste errors back to the AI)
  4. When to move on (the 3-Minute Rule)

Instructor Note

Students will be intimidated. That’s normal. Remind them: “You felt the same way before Course 2 when you built your first Power App. By the end of today, you’ll have a deployed web application. Same process, higher ceiling.”

Module 1 Complete When

  • Students can articulate the four layers of a web application
  • Students understand they won’t “learn to code” — they’ll learn to direct AI to code for them
  • Students have seen the live Heywood demo and understand the target

Module 2: Environment Setup

Duration: 45 minutes

Before we build anything, students need the right tools installed. This is the most boring module and the most critical. If the environment isn’t right, nothing else works.

Pre-Class Preparation

Ideally, send setup instructions to students before class so they arrive with tools installed. In practice, expect 30–50% to need help during this module. Have the instructor and any TAs circulate during this time.

2.1 Required Tools

Tool What It Does How to Install
Go 1.22+ Backend programming language go.dev/dl — download installer
Node.js 20+ Frontend build tools nodejs.org — LTS version
Git Version control git-scm.com — download installer
VS Code Code editor code.visualstudio.com
Docker Desktop Container runtime (Module 10) docker.com/products/docker-desktop

2.2 AI-Guided Installation

Here’s your first lesson in AI-assisted development: let the AI help you install things. Students should open their AI tool (ChatGPT, Claude, Copilot) and use this prompt:

Student Prompt to AI:

I need to set up a development environment on [Windows/Mac]. I need to install: Go 1.22 or later, Node.js 20 LTS, Git, and VS Code. Give me step-by-step instructions for my operating system, including how to verify each installation works. After installation, I should be able to run: go version, node --version, npm --version, git --version — and see version numbers for all four.

2.3 Verify the Environment

Every student should open a terminal (Command Prompt, PowerShell, or Terminal) and run:

Verification Commands
go version        # Should show: go version go1.22.x or higher
node --version    # Should show: v20.x.x or higher
npm --version     # Should show: 10.x.x or higher
git --version     # Should show: git version 2.x.x

2.4 Create the Project

Student Prompt to AI:

I’m starting a new full-stack web application. Create the initial project structure with a Go backend and React frontend. The project should be called “my-staff-app” with this structure:

  • Root directory: my-staff-app/
  • Go module initialized as “my-staff-app” in the root
  • Backend entry point at cmd/server/main.go
  • Internal packages directory at internal/
  • React app (Vite + TypeScript) in web/ subdirectory
  • Data directory at data/ for JSON seed files

Give me the exact terminal commands to create this structure and initialize both the Go module and the React app. Use Vite with the React-TypeScript template.

Expected Terminal Commands
mkdir my-staff-app
cd my-staff-app
go mod init my-staff-app
mkdir -p cmd/server internal data
npm create vite@latest web -- --template react-ts
cd web && npm install && cd ..

Instructor Checkpoint: Environment Ready

Before moving on, verify every student has:

  • All four tools installed and verified
  • The project directory created with both Go and React initialized
  • go mod init completed (go.mod file exists)
  • npm install completed in web/ (node_modules exists)

Common issues: Go not in PATH (need to restart terminal), npm create vite fails (need to update npm: npm install -g npm@latest), Docker requires admin rights (defer to Module 10).

Module 2 Complete When

  • Every student has Go, Node, Git, and VS Code installed
  • Project directory exists with go.mod and web/package.json
  • Students have used AI to guide their own installation

Module 3: Backend from Scratch

Duration: 45 minutes

This is where students write their first real server-side code — or rather, where they direct the AI to write it. By the end of this module, students will have a running HTTP server that responds to API requests with JSON.

3.1 The First Server

Student Prompt to AI:

Create a Go HTTP server in cmd/server/main.go that:

  • Starts on port 8080
  • Uses only the Go standard library (net/http), no frameworks
  • Has a health check endpoint at GET /api/v1/health that returns {"status": "ok"}
  • Uses Go 1.22 ServeMux pattern matching (method + path)
  • Logs the server start address to stdout
  • Accepts a -port flag to change the port
  • Accepts a -dev flag for development mode
Expected: cmd/server/main.go
package main

import (
    "encoding/json"
    "flag"
    "fmt"
    "log"
    "net/http"
)

func main() {
    port := flag.String("port", "8080", "server port")
    dev := flag.Bool("dev", false, "development mode")
    flag.Parse()

    mux := http.NewServeMux()

    mux.HandleFunc("GET /api/v1/health", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
    })

    addr := ":" + *port
    log.Printf("Server starting on %s (dev=%v)", addr, *dev)
    if err := http.ListenAndServe(addr, mux); err != nil {
        log.Fatal(err)
    }
}

Students run it:

Run and Test
go run ./cmd/server -dev

# In another terminal (or browser):
curl http://localhost:8080/api/v1/health
# Returns: {"status":"ok"}

First Victory

This is a critical moment. When students see {"status":"ok"} in their browser, they’ve just built their first web server. Celebrate it. They wrote zero lines of code themselves, but they directed the AI to build something real. That’s the skill.

3.2 Adding a Router

Student Prompt to AI:

Now create a separate router file at internal/api/router.go. Move the route registration into a SetupRouter function that returns an *http.ServeMux. Also create helper functions writeJSON(w, status, data) and writeError(w, status, message) in the same package. Keep the health endpoint. The main.go should call api.SetupRouter() instead of defining routes directly.

This teaches Scaffold → Flesh Out: we started with everything in main.go, now we’re separating concerns. The AI handles the refactoring.

3.3 First Data Endpoint

Student Prompt to AI:

Add a new endpoint GET /api/v1/items that returns a hardcoded JSON array of 5 items. Each item should have: id (string), title (string), status (string: “active” or “pending”), and priority (string: “high”, “medium”, “low”). Make the items relevant to a military unit — things like “Complete range safety brief” or “Submit PFT scores.”

Instructor Checkpoint: Server Running

Every student should be able to:

  • Run go run ./cmd/server -dev without errors
  • Open http://localhost:8080/api/v1/health in a browser and see JSON
  • Open http://localhost:8080/api/v1/items and see the 5-item array

Common issues: Port already in use (change to 8081), import path mismatches (go.mod module name must match import paths), missing go.sum (run go mod tidy).

Module 3 Complete When

  • Go server runs and serves JSON on two endpoints
  • Code is organized with a separate router file
  • Students have practiced the prompt → verify → iterate cycle at least twice

Module 4: Data Layer

Duration: 45 minutes

Hardcoded data is fine for testing, but real applications read from data stores. This module teaches Interface-First Design — one of the most powerful patterns in AI-assisted development.

4.1 Define the Interface

Before writing any data storage code, we define what our data layer needs to do. This is the interface — a contract that says “any data store must support these operations.”

Student Prompt to AI:

Create a Go interface in internal/data/store.go for a DataStore that manages items for a military unit application. The interface should have these methods:

  • ListItems() — returns all items
  • GetItem(id string) — returns one item by ID
  • CreateItem(item) — adds a new item
  • UpdateItem(id string, updates) — modifies an existing item

Also define the Item struct with fields: ID, Title, Description, Status, Priority, AssignedTo, CreatedAt. Use proper JSON tags. Then implement a JSONStore that reads from and writes to a JSON file in the data/ directory.

Why Interfaces Matter

This is the same pattern used in Heywood. Its DataStore interface has 27 methods and 5 different backends (JSON, SQLite, PostgreSQL, Excel, Hybrid). But the rest of the application doesn’t care which backend is active — it only talks to the interface.

When you define interfaces first, you can:

  • Start with JSON files (easy, no setup)
  • Upgrade to SQLite later (without changing any other code)
  • Switch to PostgreSQL for production (just a config change)

4.2 Create Seed Data

Student Prompt to AI:

Create a JSON seed file at data/items.json with 20 realistic items for a military training unit. Include a mix of statuses (active, pending, completed) and priorities (high, medium, low). Items should be things like equipment checks, training events, qualification deadlines, and admin tasks. Use military formatting for dates and descriptions.

4.3 Wire It Up

Student Prompt to AI:

Update cmd/server/main.go to:

  • Load the JSONStore from the data/ directory on startup
  • Pass the store to the router/handlers
  • Replace the hardcoded items endpoint with one that reads from the store
  • Add a GET /api/v1/items/{id} endpoint that returns a single item

Instructor Checkpoint: Data Layer Working

  • GET /api/v1/items returns 20 items from the JSON file
  • GET /api/v1/items/1 returns a single item
  • Students can explain what an interface is in one sentence: “A contract that defines what operations a data store must support”

Module 4 Complete When

  • DataStore interface defined with 4+ methods
  • JSONStore implementation reads from data/items.json
  • API endpoints return data from the store
  • Students understand interface-first design

Module 5: Frontend from Scratch

Duration: 45 minutes

The backend is serving data. Now we build the frontend to display it. Students will create a React application that fetches data from their Go API and renders it in the browser.

5.1 Configure the Frontend

Student Prompt to AI:

I have a React app created with Vite in my web/ directory. I need to:

  • Install and configure Tailwind CSS for styling
  • Set up a Vite proxy so /api requests forward to my Go server on port 8080
  • Create a simple API client at web/src/lib/api.ts that has a function to fetch items from /api/v1/items
  • Replace the default App.tsx with a clean starting point that shows “My Staff App” as the heading

Give me the exact commands and file contents. Use Tailwind CSS v3 with the default config.

5.2 First Component — The Items List

Student Prompt to AI:

Create a React component at web/src/pages/ItemsPage.tsx that:

  • Fetches items from the API on mount using useEffect
  • Displays them in a table with columns: Title, Status, Priority, Assigned To
  • Color-codes the Status column (green for active, yellow for pending, gray for completed)
  • Color-codes the Priority column (red for high, yellow for medium, green for low)
  • Uses Tailwind CSS classes for styling
  • Shows a loading state while fetching
  • Shows an error message if the fetch fails

5.3 Run Both Together

Students now need two terminals:

Terminal 1: Backend
go run ./cmd/server -dev
Terminal 2: Frontend
cd web && npm run dev

Open http://localhost:5173 (Vite’s dev server). The React app loads and fetches data from the Go backend via the Vite proxy. Students see their items rendered in a styled table.

Second Victory

This is another key moment. Students are now seeing data flow from a JSON file, through a Go server, into a React frontend, rendered in the browser. They built a full-stack application. Everything from here is adding features.

Instructor Checkpoint: Frontend Rendering

  • React app loads at localhost:5173
  • Items table displays data from the Go API
  • Status and priority columns are color-coded
  • No console errors in browser dev tools

Common issues: CORS errors (need the Vite proxy configured), fetch returns HTML instead of JSON (API path wrong), Tailwind not loading (PostCSS config missing). For each: paste the error into AI and let it fix it.

Module 5 Complete When

  • React app fetches and displays data from the Go API
  • Table is styled with Tailwind CSS
  • Students understand the frontend-backend relationship

Module 6: Pages & Navigation

Duration: 45 minutes

One page isn’t an application. This module adds multiple pages, client-side routing, and a navigation sidebar — turning the prototype into something that looks and feels like a real application.

6.1 Add React Router

Student Prompt to AI:

Add client-side routing to my React app using react-router-dom. Create:

  • A layout component with a dark sidebar on the left (like a military application)
  • Navigation links in the sidebar: Dashboard, Items, Settings
  • A Dashboard page that shows summary stats (total items, items by status, items by priority)
  • The existing Items page at /items
  • A placeholder Settings page
  • A header bar at the top with the app name and a user role indicator

Use Tailwind CSS. The sidebar should be dark navy (#1a1f36), links should highlight when active, and the main content area should have a light background.

6.2 Item Detail Page

Student Prompt to AI:

Add an item detail page at /items/:id that:

  • Fetches a single item from GET /api/v1/items/{id}
  • Shows all fields in a clean card layout
  • Has a back button that returns to the items list
  • Shows a 404 message if the item doesn’t exist

Also make the item titles in the table on the Items page clickable links that navigate to the detail page.

6.3 Dashboard with Stats

Student Prompt to AI:

Create a Dashboard page that fetches all items and shows:

  • Four stat cards at the top: Total Items, Active, Pending, Completed (with counts)
  • Each card should have a colored indicator (green, yellow, blue, gray)
  • Below the cards, show a “Recent Items” section with the 5 most recent items
  • Add a “Quick Actions” panel on the right with links to the Items page and Settings

Instructor Checkpoint: Multi-Page App

  • Sidebar navigation works (clicking links changes the page without full reload)
  • Dashboard shows stats calculated from the API data
  • Item detail page loads correctly from the items list
  • Active page is highlighted in the sidebar

Module 6 Complete When

  • Application has 3+ pages with sidebar navigation
  • Dashboard shows aggregated stats from API data
  • Item detail page works with dynamic routing
  • Application looks and feels like a real tool, not a prototype

Module 7: AI Chat Integration

Duration: 45 minutes

This is the inception module — using AI to build AI features. Students will add a chat interface to their application that connects to OpenAI and can query the application’s own data through tool use.

API Key Required

Students need an OpenAI API key (OPENAI_API_KEY) or Azure OpenAI credentials for this module. If keys aren’t available, the instructor should demo this module live and students can add it later. Alternatively, have one shared API key for the class.

7.1 Chat Backend

Student Prompt to AI:

Create a chat service in internal/ai/chat.go that:

  • Connects to the OpenAI API using net/http (no SDK, just raw HTTP)
  • Reads the API key from the OPENAI_API_KEY environment variable
  • Sends messages to gpt-4o with a system prompt that says: “You are a staff officer assistant for a military unit. You help manage tasks, track items, and answer questions about unit operations.”
  • Supports tool use — define a “lookup_items” tool that searches the DataStore
  • Returns the AI’s response as a string

Also create a POST /api/v1/chat endpoint that accepts {"message": "..."} and returns {"response": "..."}.

7.2 Tool Use — The AI Queries Your Data

What is Tool Use?

Tool use (also called function calling) lets the AI call functions in your application. When a user asks “How many high-priority items do I have?”, the AI doesn’t guess — it calls your lookup_items function, gets the real data, and responds with the actual count.

This is what makes Heywood powerful. It doesn’t hallucinate about student data — it queries the real database and reports facts.

Student Prompt to AI:

Define an OpenAI tool for the chat service called “lookup_items” with these parameters:

  • status (optional string) — filter by status: “active”, “pending”, “completed”
  • priority (optional string) — filter by priority: “high”, “medium”, “low”
  • query (optional string) — search term to match against title or description

When the AI calls this tool, execute the search against the DataStore and return the matching items as JSON. The AI will then use this data in its response to the user.

7.3 Chat Frontend

Student Prompt to AI:

Create a Chat page at web/src/pages/ChatPage.tsx that:

  • Has a message input at the bottom with a send button
  • Displays conversation history with user messages on the right (blue) and AI responses on the left (gray)
  • Shows a loading indicator while waiting for the AI response
  • Auto-scrolls to the latest message
  • Renders markdown in the AI’s response (bold, lists, headers)
  • Disables the input while a request is in flight

Add “Chat” to the sidebar navigation. Students can now:

  1. Open the Chat page
  2. Type “What are my high-priority items?”
  3. Watch the AI query the DataStore through tool use
  4. See the response with actual data from their application

Instructor Checkpoint: Chat Working

  • Chat page sends messages and displays responses
  • AI uses tool calling to query the DataStore (visible in server logs)
  • Response contains actual data, not hallucinated items

Common issues: API key not set (export OPENAI_API_KEY=...), CORS blocking the chat request (add CORS middleware), tool call response format wrong (the AI will help debug its own tool definitions).

Module 7 Complete When

  • Chat interface sends and receives messages
  • AI uses tool calling to query application data
  • Responses are rendered with markdown formatting
  • Students understand the concept of tool use (AI calling your code)

Module 8: Authentication & Middleware

Duration: 45 minutes

Different users should see different things. A commanding officer sees everything. A junior Marine sees only their own data. This module adds role-based authentication and middleware — the security layer that makes this possible.

8.1 Middleware Concept

Middleware is code that runs before every request reaches your handler. It’s like a gate guard — checking credentials before letting anyone into the building.

Student Prompt to AI:

Create a middleware package at internal/middleware/ with:

  • A CORS middleware that allows requests from localhost:5173 in dev mode
  • A SecurityHeaders middleware that sets standard security headers (X-Content-Type-Options, X-Frame-Options, etc.)
  • An Auth middleware that reads a “role” cookie and sets the role in the request context
  • A Chain function that composes multiple middleware together
  • Helper functions: GetRole(ctx) returns the role string from context

Valid roles are: “admin”, “staff”, “user”. If no cookie is set, default to “user”.

8.2 Role Switching (Demo Mode)

Student Prompt to AI:

Add two auth endpoints:

  • GET /api/v1/auth/me — returns the current user’s role from the cookie
  • POST /api/v1/auth/switch — accepts {"role": "admin"} and sets the role cookie

On the frontend, add a role picker dropdown in the header that lets users switch between Admin, Staff, and User roles. When switched, the page should reload to reflect the new role.

8.3 Role-Based Filtering

Student Prompt to AI:

Update the API handlers to filter data based on role:

  • Admin sees all items and all endpoints
  • Staff sees all items but cannot access Settings endpoints
  • User sees only items assigned to them (filter by AssignedTo field)

Also conditionally show/hide the Settings link in the sidebar based on role.

Instructor Checkpoint: Auth Working

  • Role picker changes the active role
  • Switching to “User” shows fewer items (only their assigned ones)
  • Settings link disappears for non-admin roles
  • Auth endpoints return correct role from cookie

Module 8 Complete When

  • Middleware chain applies CORS, security headers, and auth
  • Role picker works and persists across page loads
  • Data is filtered based on user role
  • Students understand middleware as “code that runs before every request”

Module 9: External Integrations

Duration: 45 minutes

Real applications connect to external services. This module offers two paths — students choose one based on what’s available to them:

  • Path A: Database Backend — add SQLite to replace JSON files (no external service needed)
  • Path B: Microsoft Graph — connect to Outlook calendar and mail (requires Azure AD credentials)

Choose Your Path

Path A (SQLite) is recommended for most students — it requires no external accounts and teaches a broadly useful skill. Path B (Microsoft Graph) is for students with Azure AD access who want to integrate with Outlook.

Path A: SQLite Database

Path A: Add SQLite Backend
Student Prompt to AI:

Add a SQLite database backend to my application. Create a new implementation of my DataStore interface that:

  • Uses the modernc.org/sqlite driver (pure Go, no CGO required)
  • Auto-creates the items table on startup if it doesn’t exist
  • Implements all DataStore methods using SQL queries
  • Uses parameterized queries to prevent SQL injection
  • Falls back to the JSON store if the database connection fails

Update main.go to accept a -db flag: “json” (default) or “sqlite”.

After implementation, students can run with -db sqlite and their data persists in a local database file instead of JSON. This is the exact pattern Heywood uses — same interface, different backend.

Path B: Microsoft Graph

Path B: Connect to Outlook via Microsoft Graph
Student Prompt to AI:

Create a Microsoft Graph API client in internal/msgraph/client.go that:

  • Uses OAuth2 client credentials flow (app-only, no user login)
  • Reads GRAPH_TENANT_ID, GRAPH_CLIENT_ID, GRAPH_CLIENT_SECRET from environment
  • Gets an access token and caches it until near-expiry
  • Has a Get(path, params) method for authenticated Graph API calls
  • Supports both commercial (graph.microsoft.com) and GCC High (graph.microsoft.us) endpoints

Then add endpoints:

  • GET /api/v1/calendar/today — returns today’s calendar events
  • GET /api/v1/mail/summary — returns recent email subjects and senders

Instructor Checkpoint: Integration Working

Path A: App starts with -db sqlite, data persists after restart.

Path B: Calendar and mail endpoints return real data from Outlook.

Module 9 Complete When

  • Students have connected their app to at least one external service
  • The integration works end-to-end (data flows from external source to browser)

Module 10: Docker & Deployment

Duration: 45 minutes

The application works on your laptop. Now it needs to work everywhere. Docker packages your entire application — backend, frontend, data — into a single container that runs identically on any machine.

10.1 The Dockerfile

Student Prompt to AI:

Create a multi-stage Dockerfile for my application:

  • Stage 1 (web-builder): Use node:22-alpine. Copy web/ directory, run npm ci and npm run build. Output goes to web/dist/.
  • Stage 2 (go-builder): Use golang:1.24-alpine. Copy Go source, run go build with CGO_ENABLED=0 and -trimpath -ldflags=”-s -w”. Output is a single binary.
  • Stage 3 (runtime): Use alpine:3.21. Copy the binary, the web/dist directory, and the data/ directory. Run as non-root user. Expose port 8080. Add a health check.

The Go server should serve the React build from web/dist/ in production mode (when -dev is not set). Add a SPA fallback that serves index.html for any non-API, non-asset route.

10.2 Build and Run Locally

Build and Run with Docker
docker build -t my-staff-app .
docker run -p 8080:8080 -e OPENAI_API_KEY=sk-... my-staff-app

# Open http://localhost:8080 — the full application runs from the container

Third Victory — The Big One

When students see their application running from a Docker container — with the React frontend, Go backend, and data all packaged together — they’ve crossed a fundamental threshold. This container can run on any machine in the world. A laptop, a server, Azure, a ship, a field TOC.

10.3 Deploy to Azure (Optional)

If students have Azure access, deploy the container to Azure Container Apps:

Student Prompt to AI:

Give me the Azure CLI commands to deploy my Docker container to Azure Container Apps. I need to:

  • Create a resource group
  • Create an Azure Container Registry (ACR)
  • Push my Docker image to ACR
  • Create a Container App that runs the image
  • Set environment variables for OPENAI_API_KEY
  • Get the public URL of the deployed app

Use the Azure CLI (az command). My app name is “my-staff-app”.

Instructor Checkpoint: Deployed

Minimum: Docker container runs locally on port 8080, serves the full application.

Ideal: Container deployed to Azure with a public URL that works.

Common issues: Docker not installed (they need Docker Desktop), build fails on node_modules (need .dockerignore), image too large (make sure multi-stage build is correct), Azure login issues (az login first).

Module 10 Complete When

  • Docker image builds successfully
  • Container runs locally and serves the full application
  • Students understand that one container = entire application
  • (Bonus) Application deployed to Azure with a public URL

Assessment & Wrap-Up

Duration: 15 minutes

Assessment Criteria

Students have successfully completed Course 6 when they have a deployed application that meets:

Criterion Minimum Target
API Endpoints 3 endpoints returning JSON 5+ endpoints with CRUD operations
Frontend Pages 2 pages with navigation 4+ pages with sidebar, routing, and detail views
Data Layer Reads from JSON files Interface-based with upgradeable backend
AI Integration Chat sends/receives messages Tool use queries live data
Authentication Role picker in UI Role-based data filtering
Deployment Docker container runs locally Deployed to Azure with public URL

Frontier Map Update

Have each student update their personal frontier map from Course 1. New capabilities to add:

  • Can now do: Build and deploy a full-stack web application using AI assistance
  • Still learning: Complex database design, production security hardening, CI/CD pipelines
  • Next frontier: What problem at your unit needs a custom application that Power Platform can’t solve?

What Comes Next

This course gave you the foundation. The real learning happens when you build something for your own unit. Here’s the recommended progression:

  1. Week 1–2: Rebuild today’s application from scratch without looking at the prompts. This builds muscle memory.
  2. Week 3–4: Identify a real problem at your unit. Define requirements using the Problem Definition Worksheet from Course 3.
  3. Week 5–8: Build it. Use the same prompt → verify → iterate cycle. Expect 80–120 hours for your first real full-stack tool.
  4. Week 9+: Deploy, get feedback, iterate. Document everything using the Documentation Package template.

Time Expectations

Your first real full-stack application will take 80–120 hours. That’s 2–3 weeks of focused work. Your second will take 40–60 hours. Your third, 20–30. The skill compounds — you get faster because you learn what to ask for and how to structure your conversations with AI.

For comparison: a contractor would quote 6–12 months and $500K+ for the same application.

Course 6 Complete

You just built and deployed a full-stack web application. You wrote the requirements. AI wrote the code. You verified it worked. You deployed it to the cloud.

That’s not “learning to code.” That’s Expert-Driven Development at the highest level — domain experts building exactly what they need, at the speed of conversation.