πŸ—οΈ Day 5 Afternoon • Sprint Lab

Sprint Kickoff:
Building Your
AI-EO Application

From architecture to working code. You have your design from this morning and feedback from Factory 2026. Now, it is time to build. This session is your dedicated construction time with instructor support.

πŸ“… Friday, June 12, 2026
πŸ•‘ 14:00 - 16:00
πŸ“ ISU, Strasbourg
πŸ—οΈ Hands-On Lab
Section 1

Sprint Methodology

Today we adopt an agile sprint approach to building your application. A sprint is a short, focused burst of development with clear goals and check-ins. This is how professional software teams work, and it is how you will build your AI-EO prototype today.1

πŸ“‹ Plan
β†’
πŸ”¨ Build
β†’
πŸ§ͺ Test
β†’
πŸ”„ Iterate

Why Sprints Work for Prototyping

  • Time-boxed focus: Two hours of dedicated building with clear start and end points
  • Incremental delivery: Ship small pieces that work rather than one big piece that does not
  • Rapid feedback: Test each feature as you build it, then correct course immediately
  • Reduced scope creep: A sprint forces you to prioritize ruthlessly
πŸ’‘

Key Principle: The goal is not perfection. The goal is a working skeleton. Get the core feature running first, then improve it. A working demo with rough edges beats a polished mockup with no functionality.

Your Sprint Backlog

Prioritize these items in order. Each one builds on the previous:

  1. Map renders with base tiles and correct initial view
  2. Chat UI sends and displays messages
  3. AI responds to user queries via the Gemini API
  4. Map reacts to AI instructions (markers, layers, zoom)
  5. Polish: error handling, loading states, styling
Section 1

Today's Goal: A Working Skeleton

By the end of this two-hour session, you should have a functional application skeleton where the core feature works end-to-end. This means a user can interact with your app and see meaningful results, even if the interface is rough.

πŸ—ΊοΈ

Interactive Map

Leaflet map with base tiles, centered on your study area, responding to programmatic commands

πŸ’¬

Chat Interface

Input field and message display where users can type queries and see AI responses

πŸ€–

AI Integration

Gemini API connection that processes user questions and returns structured responses

πŸ”—

Connected Pipeline

User input triggers AI, which triggers map actions: the full loop working together

⚠️

Scope Discipline: Resist the temptation to add features. Do not add satellite data overlays, multi-layer controls, or fancy animations today. Get the skeleton working first. You will have all of next week to add features and polish.

Work Format

This is individual or team work with floating instructor support. Work at your own pace. Raise your hand or post in the class channel when you get stuck. Check in at the milestone times on the schedule. Help each other: if you solved a problem, share the solution.

Section 2

Template Repository Structure

Your project follows the architecture you designed this morning. Here is the standard folder structure for an AI-EO web application. Every file has a clear purpose and a single responsibility.2

πŸ“ my-ai-eo-app/ β”œβ”€β”€ index.html # Entry point: layout, styles, script imports β”œβ”€β”€ πŸ“ js/ β”‚ β”œβ”€β”€ app.js # Orchestrator: wires everything together β”‚ β”œβ”€β”€ ai-service.js # Gemini API: config, fetch, parse, errors β”‚ β”œβ”€β”€ map-service.js # Leaflet: init, markers, layers, fly-to β”‚ └── ui.js # DOM: render messages, loading states β”œβ”€β”€ πŸ“ css/ β”‚ └── style.css # All custom styles β”œβ”€β”€ πŸ“ data/ β”‚ └── locations.json # Optional: predefined locations/datasets β”œβ”€β”€ .gitignore # Excludes node_modules, .env, etc. └── README.md # Project description, setup instructions

Why This Structure?

  • Separation of Concerns: Each module handles one thing. AI logic does not touch the DOM. Map logic does not call APIs.
  • Testability: You can test each module independently
  • Team-friendly: Two people can work on different modules without merge conflicts
  • Scalability: Easy to add new features (e.g., a satellite-service.js) without modifying existing code
πŸ“Œ

Simplified Start: For today's sprint, you may start with a single index.html file containing everything inline. This reduces setup friction. You can refactor into separate files tomorrow or next week.

Section 2

Starter Code: HTML + Leaflet + Chat Panel

Here is the complete HTML shell for your application. It provides a split-screen layout: a Leaflet map on the left and a chat sidebar on the right. Copy this as your starting point.

index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My AI-EO App</title>
  <link rel="stylesheet"
    href="https://unpkg.com/leaflet/dist/leaflet.css">
  <style>
    body { margin: 0; display: flex;
           height: 100vh; font-family: sans-serif; }
    #map  { flex: 1; }
    #sidebar {
      width: 400px; display: flex;
      flex-direction: column;
      background: #0d1224; color: #f9fafb;
    }
    #chat-messages {
      flex: 1; overflow-y: auto; padding: 1rem;
    }
    #chat-input-area {
      display: flex; padding: 0.5rem;
      gap: 0.5rem;
      border-top: 1px solid rgba(255,255,255,0.1);
    }
    #chat-input {
      flex: 1; padding: 0.75rem;
      border: 1px solid rgba(255,255,255,0.1);
      background: rgba(255,255,255,0.05);
      color: white; border-radius: 8px;
    }
    .msg {
      padding: 0.75rem; margin: 0.5rem 0;
      border-radius: 12px; max-width: 85%;
    }
    .msg.user { background: #10b981;
                  margin-left: auto; }
    .msg.ai   { background: rgba(255,255,255,0.05); }
  </style>
</head>
<body>
  <div id="map"></div>
  <div id="sidebar">
    <div id="chat-messages"></div>
    <div id="chat-input-area">
      <input id="chat-input"
        placeholder="Ask about any location...">
      <button onclick="sendMessage()">Send</button>
    </div>
  </div>
  <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
</body>
</html>
βœ…

Copy this exactly. Save it as index.html, open it in your browser, and confirm you see a map on the left and a dark sidebar on the right. If that works, you have a foundation to build on.

Section 2

AI Service Module

The AI service module handles all communication with the Gemini API. It encapsulates configuration, request formatting, response parsing, and error handling in one place.3

js/ai-service.js
// ============================================
// AI SERVICE MODULE
// Handles all Gemini API communication
// ============================================

const AI_CONFIG = {
  apiKey:  'YOUR_API_KEY_HERE',
  model:   'gemini-2.0-flash',
  baseUrl: 'https://generativelanguage.googleapis.com/v1beta',
};

// Build the API endpoint URL
function getEndpoint() {
  return `${AI_CONFIG.baseUrl}/models/${AI_CONFIG.model}:generateContent?key=${AI_CONFIG.apiKey}`;
}

// Send a prompt to Gemini and get a response
async function askGemini(userMessage, systemPrompt) {
  const body = {
    contents: [{
      role: 'user',
      parts: [{ text: userMessage }]
    }],
    systemInstruction: {
      parts: [{ text: systemPrompt }]
    }
  };

  try {
    const res = await fetch(getEndpoint(), {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body)
    });

    if (!res.ok) {
      throw new Error(`API Error: ${res.status}`);
    }

    const data = await res.json();
    return data.candidates[0]
               .content.parts[0].text;
  } catch (err) {
    console.error('Gemini error:', err);
    return 'Sorry, I could not process that request. Please check your API key and try again.';
  }
}

Key Design Decisions

  • Centralized config: API key and model name in one object; easy to change
  • Error boundaries: try/catch ensures the app never crashes from a failed API call
  • Single responsibility: This module only talks to the AI. It does not touch the DOM or the map.
πŸ”’

Security Note: Never commit your API key to a public GitHub repository. For this class exercise, embedding the key in client-side code is acceptable. For production apps, always use a backend proxy or environment variables.

Section 2

Map Service Module

The map service module wraps all Leaflet interactions. It initializes the map, manages markers and layers, and provides clean functions that other modules can call to update the map display.4

js/map-service.js
// ============================================
// MAP SERVICE MODULE
// Manages Leaflet map and all geospatial UI
// ============================================

let map;
let markersLayer;

// Initialize the map with default view
function initMap(containerId, center, zoom) {
  map = L.map(containerId).setView(center, zoom);

  L.tileLayer(
    'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    { attribution: '&copy; OpenStreetMap' }
  ).addTo(map);

  // Layer group for dynamic markers
  markersLayer = L.layerGroup().addTo(map);

  return map;
}

// Add a marker with a popup
function addMarker(lat, lng, popupText) {
  const marker = L.marker([lat, lng])
    .bindPopup(popupText);
  markersLayer.addLayer(marker);
  return marker;
}

// Fly to a location with animation
function flyTo(lat, lng, zoom = 10) {
  map.flyTo([lat, lng], zoom, {
    duration: 1.5
  });
}

// Clear all dynamic markers
function clearMarkers() {
  markersLayer.clearLayers();
}

Leaflet Essentials to Remember

πŸ“

Container Height

The map container must have explicit height. Use height: 100vh or flex: 1.

πŸ—‚οΈ

Layer Groups

Use L.layerGroup() to manage markers. Makes it easy to add, remove, and clear.

✈️

flyTo vs setView

flyTo() animates the transition. setView() jumps instantly. Both take [lat, lng].

Section 2

The Orchestrator: app.js

The app.js file is the conductor of your application. It does not contain business logic itself; instead, it wires the AI service, map service, and UI together into a coherent flow.

js/app.js
// ============================================
// APP ORCHESTRATOR
// Connects AI, Map, and UI modules
// ============================================

// System prompt: tells the AI how to behave
const SYSTEM_PROMPT = `You are an Earth observation
assistant. When the user asks about a location,
respond with a JSON object containing:
- "text": your explanation (1-2 paragraphs)
- "location": { "lat": number, "lng": number }
- "zoom": suggested zoom level (1-18)
- "marker": text for the map marker popup
Always respond in valid JSON only.`;

// Initialize the map on page load
initMap('map', [48.57, 7.75], 6);

// Main message handler
async function sendMessage() {
  const input = document
    .getElementById('chat-input');
  const text = input.value.trim();
  if (!text) return;

  // 1. Show user message
  addChatMessage(text, 'user');
  input.value = '';

  // 2. Call AI
  const raw = await askGemini(text, SYSTEM_PROMPT);

  // 3. Parse and act
  try {
    const data = JSON.parse(raw);
    addChatMessage(data.text, 'ai');
    if (data.location) {
      flyTo(data.location.lat,
            data.location.lng, data.zoom);
      addMarker(data.location.lat,
               data.location.lng, data.marker);
    }
  } catch {
    addChatMessage(raw, 'ai');
  }
}

// Simple chat message renderer
function addChatMessage(text, role) {
  const div = document.createElement('div');
  div.className = `msg ${role}`;
  div.textContent = text;
  const container = document
    .getElementById('chat-messages');
  container.appendChild(div);
  container.scrollTop = container.scrollHeight;
}
🧩

The JSON Pattern: By asking Gemini to respond in JSON, we get structured data we can parse programmatically. The try/catch around JSON.parse is essential because LLMs do not always produce valid JSON. The fallback displays the raw text.

Section 2

Complete Starter Scaffold

Here is the complete, self-contained starter application. This single file includes the HTML layout, all styles, and the full JavaScript for AI integration, map control, and chat UI. Copy this and replace YOUR_API_KEY_HERE with your Gemini API key to get a working prototype.

index.html (complete, ~180 lines)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My AI-EO App</title>
  <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css">
  <style>
    /* === LAYOUT === */
    * { margin:0; padding:0; box-sizing:border-box; }
    body { display:flex; height:100vh;
           font-family: 'Outfit', sans-serif; }
    #map { flex:1; }
    #sidebar {
      width:400px; display:flex; flex-direction:column;
      background:#0d1224; color:#f9fafb;
    }
    #chat-header {
      padding:1rem; font-weight:700;
      border-bottom:1px solid rgba(255,255,255,0.1);
      font-size:1.1rem;
    }
    #chat-messages { flex:1; overflow-y:auto; padding:1rem; }
    #chat-input-area {
      display:flex; padding:0.5rem; gap:0.5rem;
      border-top:1px solid rgba(255,255,255,0.1);
    }
    #chat-input {
      flex:1; padding:0.75rem;
      border:1px solid rgba(255,255,255,0.1);
      background:rgba(255,255,255,0.05);
      color:white; border-radius:8px;
      font-family:inherit; font-size:0.9rem;
    }
    #send-btn {
      padding:0.75rem 1.25rem; background:#10b981;
      color:white; border:none; border-radius:8px;
      font-weight:600; cursor:pointer;
    }
    #send-btn:hover { background:#059669; }
    /* === MESSAGES === */
    .msg { padding:0.75rem; margin:0.5rem 0;
           border-radius:12px; max-width:85%;
           line-height:1.5; font-size:0.9rem; }
    .msg.user { background:#10b981; margin-left:auto; }
    .msg.ai   { background:rgba(255,255,255,0.05); }
    .msg.loading { opacity:0.6; font-style:italic; }
  </style>
</head>
<body>
  <div id="map"></div>
  <div id="sidebar">
    <div id="chat-header">🌍 AI Earth Observer</div>
    <div id="chat-messages"></div>
    <div id="chat-input-area">
      <input id="chat-input" placeholder="Ask about any location..."
        onkeydown="if(event.key==='Enter') sendMessage()">
      <button id="send-btn" onclick="sendMessage()">Send</button>
    </div>
  </div>
  <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
  <script>
  // ====== CONFIG ======
  const API_KEY = 'YOUR_API_KEY_HERE';
  const MODEL  = 'gemini-2.0-flash';
  const SYSTEM = `You are an Earth observation
  assistant. Respond in JSON: {"text":"...",
  "location":{"lat":0,"lng":0}, "zoom":10,
  "marker":"popup text"}. Always valid JSON.`;

  // ====== MAP ======
  const map = L.map('map').setView([48.57,7.75],6);
  L.tileLayer('https://{s}.tile.openstreetmap.org'
    + '/{z}/{x}/{y}.png').addTo(map);
  const markers = L.layerGroup().addTo(map);

  // ====== AI ======
  async function askAI(prompt) {
    const url = `https://generativelanguage.googleapis.com/v1beta/models/`
      + `${MODEL}:generateContent?key=${API_KEY}`;
    const r = await fetch(url, {
      method:'POST',
      headers:{'Content-Type':'application/json'},
      body: JSON.stringify({
        contents:[{role:'user',
          parts:[{text:prompt}]}],
        systemInstruction:{parts:[{text:SYSTEM}]}
      })
    });
    const d = await r.json();
    return d.candidates[0].content.parts[0].text;
  }

  // ====== CHAT ======
  function addMsg(text, role) {
    const el = document.createElement('div');
    el.className = `msg ${role}`;
    el.textContent = text;
    const c = document.getElementById('chat-messages');
    c.appendChild(el); c.scrollTop = c.scrollHeight;
    return el;
  }

  async function sendMessage() {
    const inp = document.getElementById('chat-input');
    const q = inp.value.trim();
    if(!q) return;
    addMsg(q, 'user'); inp.value = '';
    const loading = addMsg('Thinking...', 'ai loading');
    try {
      const raw = await askAI(q);
      loading.remove();
      const data = JSON.parse(
        raw.replace(/```json?\n?/g,'')
           .replace(/```/g,'').trim()
      );
      addMsg(data.text, 'ai');
      if(data.location) {
        map.flyTo([data.location.lat,
          data.location.lng], data.zoom||10);
        L.marker([data.location.lat,
          data.location.lng])
          .bindPopup(data.marker||'πŸ“')
          .addTo(markers).openPopup();
      }
    } catch(e) {
      loading.remove();
      addMsg('Error: '+e.message, 'ai');
    }
  }
  </script>
</body>
</html>
πŸš€

This is your launchpad. Every student should have this running within the first 15 minutes. Everything you build from here is customization: your own system prompt, your own study area, your own unique features.

Section 3

Work Session Structure

The remaining time is yours to build. We structure it as a series of short sprints with brief check-ins to maintain momentum and catch problems early.

Time Activity Goal
14:00 - 14:15 Setup Sprint Scaffold running, map visible, sidebar visible
14:15 - 14:45 Core Sprint 1 AI responds to chat input with text
14:45 - 14:50 Check-in #1 Show a working AI response to the class
14:50 - 15:30 Core Sprint 2 AI responses drive map actions (flyTo, markers)
15:30 - 15:35 Check-in #2 Demo the full chat-to-map pipeline
15:35 - 15:55 Polish Sprint Error handling, loading states, custom system prompt
15:55 - 16:00 Wrap-up Git commit, push, progress reflection
🎯

The 15-Minute Rule: If you have been stuck on the same problem for 15 minutes, stop and ask for help. Do not waste sprint time debugging alone. The instructor and your classmates are resources; use them.

Section 3

Getting Unstuck: Troubleshooting Guide

These are the most common issues students encounter during the first build session. Before asking for help, check this list. Most problems have a quick fix.

πŸ”΄ "AI not responding"
Check 1: Is your API key correct? Copy it fresh from Google AI Studio.
Check 2: Open the browser console (F12). Look for HTTP 400 or 403 errors.
Check 3: Are you hitting rate limits? The free tier has per-minute request limits (check your quota at Google AI Studio).
Check 4: Is the model name spelled correctly? Use gemini-2.0-flash (not gemini-pro).
πŸ”΄ "Map not rendering" (grey box or no tiles)
Check 1: Does the map container (#map) have explicit height? It needs height: 100vh or flex: 1 inside a flex parent.
Check 2: Is the Leaflet CSS loaded before the JS? CSS must come first.
Check 3: Check the tile URL. The {s} subdomain placeholder is required.
πŸ”΄ "JSON.parse error" (AI returns text, not JSON)
Fix: LLMs sometimes wrap JSON in markdown code fences. Strip them:
raw.replace(/```json?\n?/g, '').replace(/```/g, '').trim()
Also add a try/catch fallback that displays raw text when parsing fails.
πŸ”΄ "Function calling not working"
Check 1: Validate your tool schema with JSONLint.
Check 2: Check the response: is candidates[0].content.parts an array? Look for functionCall objects.
Check 3: Your system prompt must clearly describe when to use each tool.
πŸ”§

Pro Tip: Keep the browser console open at all times. Most errors appear there first. Use console.log() liberally during development; remove them before presenting.

Quiz

Quick Check: Debug Skills

Q1. Your Leaflet map shows a grey area with no tiles. What is the most likely cause?

Q2. The Gemini API returns a 429 status code. What does this mean?

Q3. Why do we ask the AI to respond in JSON instead of plain text?

Section 3

Mandatory Team Git Exercise

Before you write any project code, your team must complete this Git collaboration drill to prevent overwriting each other's code during the sprint:

⚠️
The Git Collaboration Drill:
  1. One person creates the GitHub repository and adds the others as Collaborators.
  2. Everyone clones the repository locally.
  3. Everyone creates their own branch (git checkout -b feature-test).
  4. Everyone edits the same line of the README.md file, commits, and pushes their branch.
  5. Open Pull Requests for all branches. The first one will merge cleanly. The others will have a Merge Conflict.
  6. Resolve the merge conflict together as a team on the GitHub UI or locally.

Using GitHub Copilot During the Sprint

GitHub Copilot (or any AI coding assistant) can dramatically accelerate your development during the sprint. The key is knowing when to trust it and when to verify.5

βœ… Great Uses

  • Boilerplate code: "Create a function to format a date string"
  • CSS styling: "Style this button with a gradient and hover effect"
  • Error handling patterns: "Add try/catch with user-friendly error messages"
  • Documentation: "Add JSDoc comments to this function"
  • Repetitive patterns: Multiple similar event handlers, form fields

⚠️ Verify Carefully

  • API endpoints: Copilot may hallucinate URLs that do not exist
  • Gemini API syntax: Always check against the official docs
  • Leaflet methods: Verify method signatures against Leaflet docs
  • Complex logic: Multi-step data transformations
  • Security patterns: Authentication, key management
πŸ’‘

Copilot Tip: Write a clear comment describing what you want before you start typing code. Copilot generates better suggestions when it has a natural language description to work from. For example: // Parse the AI response JSON, extract lat/lng, and fly the map to that location

When to Debug Yourself vs. Ask for Help

  • Debug yourself: Typos, missing semicolons, wrong variable names, CSS layout issues
  • Ask Copilot: "Why is this function returning undefined?" (paste the function)
  • Ask the instructor: Architecture questions, API design choices, "am I on the right track?"
Section 3

Milestone Checkpoints

Use these checkpoints to gauge your progress. If you are behind, focus on the current milestone. If you are ahead, move to the next one. Do not skip ahead; each milestone builds on the previous.

🏁

By 14:30 (30 min in)

  • βœ“ HTML template saved and open in browser
  • βœ“ Map renders with tiles visible
  • βœ“ Sidebar visible with chat input
  • βœ“ API key inserted into config
🎯

By 15:00 (60 min in)

  • βœ“ User messages display in chat
  • βœ“ AI responds with text in chat
  • βœ“ Loading indicator appears while waiting
  • βœ“ Errors caught and displayed gracefully
πŸš€

By 15:30 (90 min in)

  • βœ“ AI responses parsed as JSON
  • βœ“ Map flies to locations from AI
  • βœ“ Markers appear with popup text
  • βœ“ Full loop: type question, see map react
✨

By 16:00 (end)

  • βœ“ Custom system prompt for your topic
  • βœ“ Initial study area set for your project
  • βœ“ At least one unique feature added
  • βœ“ Code committed to Git
πŸ†

Success Metric: If you can type a location into the chat, get an AI response, and see the map fly to that location with a marker, you have achieved today's primary objective. Everything beyond that is a bonus.

Section 4

Git Commit and Push Your Work

Before you leave today, commit and push your code. This is a non-negotiable professional habit. Your repository is your safety net and your progress tracker.6

Terminal
# Stage all changes
git add .

# Commit with a descriptive message
git commit -m "feat: initial scaffold with map + chat + AI integration"

# Push to your remote repository
git push origin main

Commit Message Best Practices

  • Be specific: "Add AI service module with error handling" is better than "update code"
  • Use conventional prefixes: feat: for features, fix: for bugs, docs: for documentation
  • Reference what works: "feat: chat sends messages and displays AI responses"
⚠️

Before pushing: Make sure your .gitignore excludes any file containing your API key. If you used an inline key in index.html, add a comment reminding yourself to move it to a config file or environment variable before making the repo public.

Progress Reflection

Take two minutes to answer these questions in your README or a notebook:

  1. What works? List the features that are functional right now.
  2. What is broken? Note any bugs or incomplete features.
  3. What is next? Your top 3 priorities for the next work session.
Section 4

Looking Ahead: Next Week

You now have a working skeleton. Next week, we add muscle and skin. Here is what is coming:

πŸ›°οΈ

Satellite Data APIs

Connect to real EO data sources: Sentinel Hub, Google Earth Engine, NASA FIRMS. Overlay actual satellite imagery on your map.

🎨

UX Polish

Responsive design, dark/light theme toggle, loading animations, accessibility improvements, mobile support.

πŸ§ͺ

Testing & Edge Cases

What happens when the API is down? When the user sends gibberish? When coordinates are invalid? Build resilience.

🎀

Final Presentations

Prepare a 5-minute demo of your working application. Show the problem, the solution, and a live walkthrough.

Weekend Challenge (Optional)

If you want a head start for next week, try these stretch goals:

  • Multiple base maps: Add a layer switcher (satellite, terrain, street) using L.control.layers()
  • Conversation history: Send the last 3 messages as context to Gemini for multi-turn conversations
  • Custom markers: Use Leaflet's L.divIcon to create styled markers that match your app theme
  • GeoJSON overlay: Load a GeoJSON file of country or region boundaries and display them on the map
πŸ“š

Recommended Reading: Review the Gemini Function Calling documentation before Monday. Next week we will use function calling to give the AI direct control over map operations.

Summary

Summary of Big Ideas

1. Working Software Over Perfect Plans

A functioning prototype with rough edges teaches you more than a detailed architecture document. Get code running, then improve it iteratively.

2. Separation of Concerns is Not Optional

AI logic, map logic, and UI logic should live in separate modules. This makes debugging possible and collaboration practical. When something breaks, you know exactly where to look.

3. Structured AI Output Enables Automation

Asking the LLM to respond in JSON transforms it from a chat tool into a programmable component. Structured output is the bridge between natural language and application logic.

4. Error Handling is a Feature, Not an Afterthought

Every external API call can fail. Every user input can be unexpected. Wrapping your code in try/catch blocks and providing graceful fallbacks is what separates a demo from a product.

5. Sprint Discipline Drives Delivery

Time-boxed work with clear milestones prevents scope creep and ensures you ship something usable. Prioritize ruthlessly: core feature first, polish later.

Reference

Glossary & References

Glossary of Key Terms

Sprint
A short, time-boxed period of focused development (typically 1 to 4 weeks in professional settings, 2 hours for us today) with clear deliverables.
Scaffold
A minimal but functional project structure that provides the foundation for further development. Like construction scaffolding, it supports the work being built on top of it.
Template
A reusable starting point (HTML file, project structure) that provides common boilerplate code and patterns to accelerate new projects.
Module
A self-contained unit of code with a single responsibility (e.g., AI communication, map rendering) that exposes functions for other modules to use.
Debug
The process of finding and fixing errors (bugs) in code. Involves reading error messages, using console.log(), and systematically isolating the problem.
Git Commit
A snapshot of your project at a specific point in time. Each commit records what changed, when, and why (via the commit message).
Milestone
A significant checkpoint in a project where specific features or goals should be completed. Used to track progress and maintain accountability.
Checkpoint
A scheduled moment during a sprint to pause, assess progress, share status, and course-correct if needed. Prevents silent failures.

References & Resources

  • [1] Schwaber, K. & Sutherland, J. (2020). "The Scrum Guide." Scrum.org. Available at: scrumguides.org
  • [2] Osmani, A. (2023). "Learning JavaScript Design Patterns," 2nd ed. O'Reilly Media. ISBN: 978-1-098-13987-2. Available at: patterns.dev
  • [3] Google. (2024). "Gemini API: Generate Content." Google AI for Developers. Available at: ai.google.dev/api/generate-content
  • [4] Agafonkin, V. (2024). "Leaflet API Reference." Leaflet. Available at: leafletjs.com/reference.html
  • [5] Peng, S., et al. (2023). "The Impact of AI on Developer Productivity: Evidence from GitHub Copilot." arXiv. DOI: 10.48550/arXiv.2302.06590
  • [6] Chacon, S. & Straub, B. (2014). Pro Git, 2nd ed. Apress. Available at: git-scm.com/book

Useful Links

🌟 Pioneer Profile
πŸ‘€

Margaret Hamilton

Software Engineer

She led the MIT team that developed the onboard flight software for the Apollo space program, coining the term 'software engineering'.

🌍 Local to Global

Global Data, Local Impact

Applying EO to Community Challenges

Earth Observation provides a macroscopic view of environmental trends, but its true power lies in downscaling this data to affect local policy and design, such as urban planning and sustainable workplaces.

πŸ“
Texas Connection: In Texas, EO data is used to monitor the Edwards Aquifer depletion and track the expansion of urban heat islands across the Dallas-Fort Worth metroplex.
πŸ—ΊοΈ
πŸ€” Geographic Inquiry

Regional Decisions Scenario

Scenario: Designing for Placemaking at Work

As you build your architecture, you must consider the human element. How does your software enable meaningful connection in a remote or hybrid setting?

Your Task:

  • Define the frontend architecture.
  • Explain how the UI promotes a sense of 'Third Place'.
πŸ“š Summary

Big Ideas & Glossary

Summary of Big Ideas

  • Data is only as valuable as its application.
  • Space technology has direct terrestrial benefits.

Glossary of Terms

Earth Observation
Gathering information about Earth via remote sensing.
πŸ“ Knowledge Check

Auto-Graded Quiz

In the context of the IPAT equation (Impact = Population Γ— Affluence Γ— Technology), how does hybrid work technology affect environmental impact?
A
It inherently always reduces the impact to zero.
B
It alters the 'Technology' multiplier, potentially reducing commute emissions but increasing server energy use.
C
It has no effect on environmental impact.
βœ… Correct! Technology is a multiplier in IPAT. Hybrid work reduces transit emissions but shifts the energy burden to data centers and home heating/cooling.
❌ Incorrect. The right answer was B. Technology is a multiplier in IPAT. Hybrid work reduces transit emissions but shifts the energy burden to data centers and home heating/cooling.

πŸ“ Daily Reflection

What was your biggest takeaway from this session, and how does it apply to the TERRA project? Write your response below. Your instructor will review this to track your progress.