<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Flask on Londopy</title><link>https://londopy.github.io/blog/tags/flask/</link><description>Recent content in Flask on Londopy</description><image><title>Londopy</title><url>https://londopy.github.io/blog/og-image.png</url><link>https://londopy.github.io/blog/og-image.png</link></image><generator>Hugo</generator><language>en-us</language><copyright>2026 Londopy · Posts CC BY 4.0 · Code MIT</copyright><lastBuildDate>Sat, 26 Sep 2026 02:30:55 -0700</lastBuildDate><atom:link href="https://londopy.github.io/blog/tags/flask/index.xml" rel="self" type="application/rss+xml"/><item><title>The App That Reports You Missing</title><link>https://londopy.github.io/blog/posts/diresq/</link><pubDate>Sat, 26 Sep 2026 09:00:00 -0700</pubDate><guid>https://londopy.github.io/blog/posts/diresq/</guid><description>During Hurricane Harvey, volunteers in fishing boats saved thousands of people, and nobody kept track of the volunteers. We built the first version of DiresQ in one 14-hour night at our first hackathon ever, kept building it for four more hackathons, and it placed 3rd in the Software Development track at Reverie Hacks 2026. Here&amp;#39;s how it works, and the three times our own code lied to us.</description><content:encoded><![CDATA[<p>During Hurricane Harvey in 2017, ordinary people took their own fishing boats into the floodwater and pulled thousands of their neighbors off roofs. Some of them didn&rsquo;t come back.</p>
<p>Here&rsquo;s the detail that stuck with me: when a volunteer like that heads out, <strong>nobody writes down that they went</strong>. There&rsquo;s no dispatcher, no roster, no log. If they stop answering their phone, nothing notices. Eventually, someone realizes they haven&rsquo;t heard from them in a while.</p>
<p>One dispatcher, interviewed afterward by disaster researchers, described trying to keep track of who was out on a boat and who had come back, and asking the question nobody could answer: &ldquo;can we account for everyone?&rdquo;</p>
<p>So my teammate and I built an app that answers it. If you go out and stop checking in, it notices. And if you stay quiet long enough, it files a report about you, at the last place anyone knew you were, so someone can come find you.</p>
<p>It&rsquo;s called <strong>DiresQ</strong>. We built the first version in a single 14-hour night for Katy Youth Hacks 2026, the first hackathon either of us had ever entered. Then we kept building it and entered it in four more. It placed <strong>3rd in the Software Development track at Reverie Hacks 2026</strong>, an online hackathon with more than 2,100 participants and 423 submitted projects.</p>
<p>But placing isn&rsquo;t the interesting part. The interesting part is the three times our own code lied to us, and looked completely fine doing it.</p>
<p><img alt="A responder goes quiet, the accountability board turns red, and a report files itself" loading="lazy" src="/blog/posts/diresq/demo.gif"></p>
<p><em>Five responders on scene. One goes quiet. At fifteen minutes the board turns red, and the report on the right files itself.</em></p>
<h2 id="every-disaster-app-tracks-the-disaster">Every disaster app tracks the disaster</h2>
<p>Crowdsourced flood maps show where the water is. Social media shows who&rsquo;s asking for help. Agencies have dispatch systems, but only for their own people: on a roster, carrying a radio, answering to an incident commander.</p>
<p>A neighbor with a boat is none of those things. Every tool we looked at mapped the incident. We couldn&rsquo;t find one that kept a list of the people walking into it.</p>
<p>Here&rsquo;s DiresQ in about sixty seconds:</p>
<ol>
<li>A neighbor&rsquo;s street is flooding. She files a report: &ldquo;Water rising, 2 trapped.&rdquo; It lands at the top of the feed, reading <strong>0 responding</strong>.</li>
<li>You have a boat. You see her report sitting above one that already has six people on it, so you join hers and type how long before anyone should start worrying about you: &ldquo;30 min.&rdquo; Your row on the accountability board turns blue.</li>
<li>You arrive and mark yourself on scene. Your row turns green. It&rsquo;s worse than she said, so you tag the report <strong>needs more help</strong>, and it climbs the feed.</li>
<li>Then you go into a flooded house and stop checking in. Thirty minutes pass. Your row turns <strong>red</strong>, showing your last known position and how long since anyone heard from you.</li>
<li>Fifteen minutes after that, the server stops waiting for someone to notice. It files a new report, about you, at your last known position.</li>
</ol>
<p>Nobody had to notice you went quiet. That&rsquo;s the product. Everything else is how you get there.</p>
<p>But the first version we designed would have made things worse.</p>
<h2 id="our-first-design-was-wrong">Our first design was wrong</h2>
<p>We started with the obvious model: dispatch. One responder claims one report, it&rsquo;s locked, and nobody else can take it. No two people driving to the same address.</p>
<p>Then we read about Kathmandu in 2015 and Mexico City in 1985. In both, huge numbers of volunteers converged on a few highly visible collapse sites, while sites nearby had nobody at all. People dug at the building that was on television.</p>
<p>The real failure in a disaster isn&rsquo;t two people going to the same address. It&rsquo;s <strong>six hundred people going to the same address</strong> while the street two blocks over has no one. A claim lock fights the wrong problem, and sometimes a collapse genuinely needs forty people.</p>
<p>So we deleted it. Any number of people can join any report. Instead of preventing convergence, DiresQ makes it visible:</p>
<ul>
<li>Every report shows how many people are already on it.</li>
<li>People on scene can say &ldquo;we need more&rdquo; or &ldquo;we&rsquo;re overstaffed,&rdquo; and the feed reorders so the next person goes where the help isn&rsquo;t.</li>
<li>When people on scene disagree, the most cautious answer wins. An optimistic report should never be able to drown out a call for help.</li>
<li>A report nobody is going to sorts <em>above</em> one that&rsquo;s merely short-handed. A gap is worse than a queue.</li>
</ul>
<p>That was the design. Building it was a different story.</p>
<h2 id="the-first-night-on-two-clocks">The first night, on two clocks</h2>
<p>The first version was built for Katy Youth Hacks, in one 14-hour window. For me, it ran from 6pm to 8am. For my teammate, <a href="https://github.com/Skythe7">Skythe</a>, the same fourteen hours ran from 8am to 10pm. We were building the same app at opposite ends of the day. We met on the <a href="https://discord.gg/zARY5CAvkh">Coding for Teens Discord server</a>, if you&rsquo;re looking for a teammate of your own.</p>
<p>It was also my first time being part of a real team, and it felt like a preview of an actual software job. We started with a call to introduce ourselves and plan, then hung up and got to work. From there it was a steady stream of DMs, with a quick call every so often to check in. And in between came those long stretches where you just lock in and code for hours.</p>
<p>The first time the app actually worked was amazing. But it didn&rsquo;t feel like a finish line. It felt like the start of a fire. It felt good, and I immediately wanted more.</p>
<p>We split the code by folder, not by feature. Skythe owned the frontend: the page templates and styles. I owned the backend: the Flask app, the database schema, and the API. The one rule: <strong>new files are free, but editing someone else&rsquo;s needs a message first.</strong> We changed code in parallel all night and never once had a merge conflict.</p>
<p>We did have one very strange commit. At some point that night, a single commit touched 39 files, added 10,462 lines, deleted 10,462 lines, and changed nothing at all. We develop on Windows and deploy on Linux, and every line ending in the repo had silently flipped. The fix was a file most repos don&rsquo;t have: <code>.gitattributes</code>. (I liked it enough to write <a href="/blog/posts/gitattributes/">a whole post about it</a>.)</p>
<p>We also leaned on four small libraries I&rsquo;d written and published to PyPI before the hackathon: <strong>timefuzz</strong> turns &ldquo;back in a couple hours&rdquo; into a real deadline, <strong>vitalscore</strong> runs the START triage protocol, <strong>pygeospy</strong> does the map math, and <strong>patchnotes</strong> checks our changelog on every push.</p>
<p>By 8am, the git log had 65 commits from that night, and the repo had 12,579 lines of code.</p>
<p>Then our plan fell apart, and it was my fault.</p>
<h2 id="the-plan-didnt-survive-contact">The plan didn&rsquo;t survive contact</h2>
<p>The plan said the backend would put up fake &ldquo;stub&rdquo; API endpoints in the first hour, so the frontend could build against them without waiting.</p>
<p>The stubs were my job. I never wrote them. I was building the interesting part instead.</p>
<p>Skythe didn&rsquo;t wait, which was the right call. The git log tells the story: Skythe&rsquo;s first commit landed at 6:05pm my time, and by the time my first backend commit showed up at 7:40pm, there were already five complete pages in the repo, built as server-rendered templates that don&rsquo;t need the API at all. That turned out to be the better design: <strong>the whole app works with JavaScript switched off.</strong> That&rsquo;s exactly what you want from a tool for the worst day of someone&rsquo;s life, running on an old phone with one bar of signal.</p>
<p>What it cost us was agreement. With no stubs and no conversation, we each guessed at the other&rsquo;s names, and three came out different:</p>
<table>
	<thead>
			<tr>
					<th>Frontend</th>
					<th>Backend</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>HIGH</code> / <code>MEDIUM</code> / <code>LOW</code></td>
					<td>integers 1 to 4</td>
			</tr>
			<tr>
					<td><code>latitude</code> / <code>longitude</code></td>
					<td><code>lat</code> / <code>lng</code></td>
			</tr>
			<tr>
					<td><code>needs_more</code></td>
					<td><code>need_more</code></td>
			</tr>
	</tbody>
</table>
<p>The frontend&rsquo;s names won all three times, because Skythe&rsquo;s templates were real, working software and my schema was still a document nobody had run.</p>
<p>The lesson I took: <strong>unblock other people before you build your favorite part.</strong> Fifteen minutes agreeing on names would have saved every one of those mismatches.</p>
<p>And then the code started lying to us.</p>
<h2 id="lie-1-the-classifier-that-scored-100">Lie #1: the classifier that scored 100%</h2>
<p>Someone filing a report at 2am from a flooded house gets asked to pick a severity from a dropdown. They don&rsquo;t know. They&rsquo;re scared, and they aren&rsquo;t trained.</p>
<p>So DiresQ suggests one. I hand-wrote a small naive Bayes classifier, trained on 55 hand-labeled example reports. It reads your description, suggests a priority, and shows you the exact words that drove the decision. It runs in about a tenth of a millisecond with no network, and the moment you touch the dropdown yourself, it stops touching it.</p>
<p>We tested it the obvious way first: run it over its training data. It scored <strong>100%</strong>.</p>
<p>That number was worthless. It had simply memorized its 55 examples. So we measured it properly: hold one report out, train on the other 54, predict the one it had never seen, and repeat that 55 times.</p>
<table>
	<thead>
			<tr>
					<th></th>
					<th>Accuracy on unseen reports</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Always guess the most common label</td>
					<td>36%</td>
			</tr>
			<tr>
					<td>Naive Bayes alone</td>
					<td>45%</td>
			</tr>
			<tr>
					<td>Naive Bayes plus a severity word list</td>
					<td>75%</td>
			</tr>
	</tbody>
</table>
<p>Nine points better than guessing, and wrong in the worst possible direction. &ldquo;Child not breathing properly&rdquo; came back MEDIUM. &ldquo;Gas smell, whole street evacuating&rdquo; came back LOW.</p>
<p>The fix was a list of the phrases the START triage protocol treats as immediate, which took it to 75%. That measurement now runs on every push, and the build fails if it ever drops below 68%. It&rsquo;s still wrong one time in four, which is survivable only because it&rsquo;s a suggestion in a dropdown you control, not a decision.</p>
<p>Of everything that weekend, this is what taught me the most: not building the model, but learning how to test one. Working out why it scored 100%, fixing it, and publishing both numbers instead of the flattering one.</p>
<p>Then we found a subtler lie. A report typed in Spanish, &ldquo;mi madre no puede respirar&rdquo; (&ldquo;my mother can&rsquo;t breathe&rdquo;), came back LOW, 51% confident. Naive Bayes can&rsquo;t say &ldquo;I don&rsquo;t know.&rdquo; When every word is unfamiliar, it falls back to its base rates and outputs a label that looks like knowledge. Katy, Texas, where we set our demo, is more than a quarter Hispanic or Latino, so that isn&rsquo;t a hypothetical. Now, when the model doesn&rsquo;t recognize the wording, it gives no suggestion and says why.</p>
<p><strong>Why not just use an AI model?</strong> Three reasons, in order:</p>
<ol>
<li><strong>It has to explain itself.</strong> The words DiresQ shows you are the actual math behind the decision, not a separately generated explanation that could disagree with it.</li>
<li><strong>It has to be honest about being wrong.</strong> A confident paragraph from a language model is much harder to doubt, and confidently wrong sends boats to the wrong street.</li>
<li><strong>It has to work with the cell towers down.</strong> No download, no API key, no network. So the same trained model runs on the phone, too.</li>
</ol>
<p>(We did use AI tools while building DiresQ, for code and documentation. There&rsquo;s just none inside the product.)</p>
<p>Putting the model on the phone led to the strangest bug of the whole project. We&rsquo;ll get there. First, the alarm.</p>
<h2 id="lie-2-the-alarm-that-could-die-quietly">Lie #2: the alarm that could die quietly</h2>
<p>The dead man&rsquo;s switch, the part that files a report when you go quiet, started life as a background timer inside the app.</p>
<p>Then we thought about what happens when a background timer crashes: nothing. No error on screen. The board keeps rendering, every row stays green, and green reads as &ldquo;everyone&rsquo;s fine&rdquo; when it really means &ldquo;nobody&rsquo;s checking.&rdquo;</p>
<p>So we deleted the timer. DiresQ never stores whether someone is overdue. It works that out fresh every time someone loads the board, and runs the escalation check at the same moment. There&rsquo;s nothing to forget to start, and nothing that can silently die.</p>
<p>That left one honest dependency: if nobody has the board open, nothing gets checked. So the board shows when the check last ran, <strong>&ldquo;checked 2s ago,&rdquo;</strong> and turns amber if it ever stops. The thing that notices when people go quiet won&rsquo;t go quiet without saying so. (There&rsquo;s also a command you can run on a schedule, so the alarm doesn&rsquo;t depend on someone having a tab open.)</p>
<p>That became the theme of the whole project: <strong>the failure that matters is the one that leaves no trace.</strong></p>
<h2 id="lie-3-bugs-that-looked-like-working-features">Lie #3: bugs that looked like working features</h2>
<p>Every bug below passed its tests, threw no errors, and looked fine. We only found them by using the code for real.</p>
<ul>
<li><strong>Error messages that went nowhere.</strong> The backend reported errors in five places, like a wrong password, but no page ever displayed them. A rejected form just sat there looking frozen.</li>
<li><strong>A required field that wasn&rsquo;t.</strong> The report form required hidden latitude and longitude fields. Browsers skip validation on hidden fields, so a report submitted without a map pin saved with no location: invisible on the map, forever.</li>
<li><strong>A database that broke on the second run.</strong> A table added late got created but never dropped, so rebuilding an existing database stopped halfway and left it in pieces. Every test passed, because tests start from an empty database, and empty is the one case that always works.</li>
<li><strong>A phishing hole we built by accident.</strong> After you logged in, the app sent you to whatever address the link&rsquo;s <code>?next=</code> parameter said. So a link to our real login page, on our real domain, could hand you straight to someone else&rsquo;s site. The tests only checked that logging in redirected you, which it did.</li>
<li><strong>A map that would run whatever people typed.</strong> Report titles went into the map&rsquo;s pop-ups as raw HTML. A title containing the right HTML, like an image tag with an error handler, would have run its code in the browser of everyone who opened the map. We caught it at 4:36am and rebuilt the pop-ups so that text is only ever treated as text.</li>
<li><strong>A security check that searched nothing.</strong> Our CI scanned for hardcoded secrets. The fix landed four minutes after the scan did: a quoting mistake in the YAML crashed it before it searched a single file, and the failure looked like any other. We rewrote it in Python and tested it against a deliberately leaky file to prove it catches real ones.</li>
</ul>
<p>And the strangest one, from putting the classifier on the phone. We ran every example through both versions, Python on the server and JavaScript in the browser, with a test that fails on any disagreement. It found a bug within minutes: the words shown behind a suggestion were sorted by floating-point noise, because Python and V8 (the JavaScript engine in Chrome and Node) round logarithms differently in the very last bit. That bug had been in the Python since day one. With only one implementation, it was invisible.</p>
<h2 id="the-things-we-refused-to-build">The things we refused to build</h2>
<p>A tool that looks like an emergency service can do real harm by looking more capable than it is. So we wrote down everything DiresQ doesn&rsquo;t do, and put that list inside the app.</p>
<ul>
<li><strong>No identity verification.</strong> Anyone can sign up. Doing it properly needs real ID checks, and there&rsquo;s no honest weekend version. A fake check, like email confirmation, would be worse than nothing, because it looks like verification without being it.</li>
<li><strong>No calling 911.</strong> DiresQ never contacts emergency services or implies that it has. The worst failure would be someone filing a report and believing help is on the way.</li>
<li><strong>No radio, yet.</strong> A check-in packs into 22 signed bytes, small enough for a LoRa long-range radio, with a replay counter so a captured packet can&rsquo;t simply be sent again. There&rsquo;s even a gateway script to forward packets to the server. What doesn&rsquo;t exist is the radio: we don&rsquo;t have the hardware, and untested code isn&rsquo;t a feature. It&rsquo;s a file that looks like one.</li>
</ul>
<p>DiresQ has never been used in a real disaster, and it shouldn&rsquo;t be until someone who does this professionally has taken it apart.</p>
<h2 id="it-wasnt-one-night">It wasn&rsquo;t one night</h2>
<p>The 14 hours were only Katy Youth Hacks. That wanting-more feeling from the first night never went away: we kept building DiresQ and entered it in four more hackathons: STEMist Hacks IV, Reverie Hacks, the Girls In STEM Global Hackathon, and the CSC Summer Impactathon. Here&rsquo;s roughly what the git log says, in my time zone:</p>
<table>
	<thead>
			<tr>
					<th>When (Pacific time)</th>
					<th>Hours</th>
					<th>Commits</th>
					<th>What happened</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Sat Aug 1, 6pm to Sun 8am</td>
					<td>14.0</td>
					<td>65</td>
					<td>Katy Youth Hacks: the whole app, from an empty repo</td>
			</tr>
			<tr>
					<td>Sun 3pm to Mon 6am</td>
					<td>14.7</td>
					<td>40</td>
					<td>Works offline and installs on a phone; releases 1.0.0 to 1.0.2</td>
			</tr>
			<tr>
					<td>Mon 6pm to Tue 2am</td>
					<td>7.6</td>
					<td>30</td>
					<td>Map fixes, then reading the research and writing a paper</td>
			</tr>
			<tr>
					<td>Wednesday</td>
					<td>2.5</td>
					<td>12</td>
					<td>A demo clock for filming, an accessibility pass, release 1.1.0</td>
			</tr>
	</tbody>
</table>
<p>The hours run from the first commit to the last in each session, so the real total is higher: reading, testing, and filming between commits don&rsquo;t show up. Even so, that&rsquo;s about 39 hours of commits over just over four days: 147 commits (plus five setup commits from the week before), four tagged releases, and a docs site that rebuilds itself from the repo on every push. The test suite grew from 344 tests in our Katy Youth Hacks submission to 606 test functions. GitHub Actions has run 288 times so far, mostly the tests, the security scan, and the changelog check that run on every push.</p>
<p>Here&rsquo;s what those extra hours bought:</p>
<ul>
<li><strong>It works with no signal.</strong> Reports and check-ins save to your phone first and send themselves when you reconnect. Each one gets its ID before the first attempt, so a phone that dies mid-send can&rsquo;t file the same emergency twice.</li>
<li><strong>It passed an accessibility audit.</strong> A WCAG 2.1 AA audit found 22 issues across four passes, six of them critical. We fixed all 22, and a test holds each fix in place.</li>
<li><strong>It turned into a paper.</strong> By the third evening, we realized the interesting claim wasn&rsquo;t the app. It was the gap. So we read the research to check whether the gap was real, going back to the primary sources. One commit message from that night: &ldquo;Read the 1957 original instead of citing it secondhand.&rdquo; That reading became an eleven-page preprint, which says plainly that DiresQ has no users, no deployment, and no evaluation.</li>
<li><strong>It learned to be filmed.</strong> The dead man&rsquo;s switch only does something after fifteen minutes of silence, which makes for a terrible demo video. So DiresQ got a scaled clock: at 60x speed, a responder goes overdue five seconds after the page loads, and the report about them arrives fifteen seconds after that. It&rsquo;s the exact same escalation code, and a banner on screen admits that time is sped up.</li>
</ul>
<p>Then we entered Reverie Hacks 2026.</p>
<h2 id="3rd-place">3rd place</h2>
<p>I found out in the middle of a marine biology lecture. We got a two-minute break to drink some water and rest our brains, I checked my phone, and there was a DM from Skythe: we&rsquo;d placed.</p>
<p>I was freaking out internally. All I wanted to do was watch the hackathon&rsquo;s showcase video on YouTube, check Discord, check Devpost, check everything. Instead, I had to sit through the rest of the lecture.</p>
<p>The second it ended, it all hit me, and every hour felt worth it. I even told my parents, even though they don&rsquo;t understand any of the coding and tech stuff.</p>
<p>Reverie Hacks drew more than 2,100 participants and 423 submitted projects across six tracks. DiresQ took 3rd place in the Software Development track. Not bad for a project that started as our first hackathon ever.</p>
<h3 id="what-the-judges-said">What the judges said</h3>
<p>Two judges scored DiresQ out of 105 points. One gave it 96, the other 94.</p>
<table>
	<thead>
			<tr>
					<th>Category</th>
					<th>Max</th>
					<th>Judge 1</th>
					<th>Judge 2</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Real-world problem and impact</td>
					<td>25</td>
					<td>24</td>
					<td>25</td>
			</tr>
			<tr>
					<td>Technical execution</td>
					<td>25</td>
					<td>24</td>
					<td>25</td>
			</tr>
			<tr>
					<td>Innovation and originality</td>
					<td>15</td>
					<td>14</td>
					<td>12</td>
			</tr>
			<tr>
					<td>User experience and design</td>
					<td>15</td>
					<td>13</td>
					<td>12</td>
			</tr>
			<tr>
					<td>Sustainability and scalability</td>
					<td>10</td>
					<td>8</td>
					<td>6</td>
			</tr>
			<tr>
					<td>Presentation and communication</td>
					<td>10</td>
					<td>10</td>
					<td>10</td>
			</tr>
			<tr>
					<td>Bonus: exceptionality</td>
					<td>+5</td>
					<td>3</td>
					<td>4</td>
			</tr>
			<tr>
					<td><strong>Total</strong></td>
					<td><strong>105</strong></td>
					<td><strong>96</strong></td>
					<td><strong>94</strong></td>
			</tr>
	</tbody>
</table>
<p>The first judge summed up the project better than I could. The strongest part, they wrote, wasn&rsquo;t the amount of functionality but the reasoning behind it: &ldquo;the team repeatedly identifies dangerous failure modes, measures them, and designs around them.&rdquo; That&rsquo;s the whole project in one sentence.</p>
<p>The bonus points stand out, too. The rubric told judges that the bonus was reserved for the rare project that goes beyond it, and that most projects should get zero, by design. Both judges gave DiresQ some: 3 points and 4. The second judge&rsquo;s reason was how complete and disciplined the whole project was for our level.</p>
<p>They also read the code, not just the writeup. The second judge noted the exact commit they reviewed, which was the last one we pushed, and admitted to getting through about half the files.</p>
<p>The criticism was fair, too:</p>
<ul>
<li><strong>It&rsquo;s unproven.</strong> Both judges pointed out that DiresQ has never been used in a real disaster, learned from only 55 examples, and relies on self-reported locations. The first judge noted that being upfront about those limits made the submission more credible, but also means its real-world effectiveness is still unproven.</li>
<li><strong>The writeup was ahead of the interface.</strong> The second judge found that some flows we described, like joining a report and voting on staffing, looked rougher in the actual app than in our writeup. That&rsquo;s a fair hit.</li>
<li><strong>Scale isn&rsquo;t solved.</strong> Moderation, identity checks, and hosting costs at scale are all written down, but none of them are solved. Sustainability was our lowest-scoring category on both sheets.</li>
</ul>
<p>Both criticisms point to the same next step, and it isn&rsquo;t a feature. It&rsquo;s talking to people who have actually coordinated volunteers in a disaster, to find out whether the gap we designed for is as real as it looks from the research.</p>
<h2 id="what-id-tell-myself-before-the-next-hackathon">What I&rsquo;d tell myself before the next hackathon</h2>
<ul>
<li><strong>Name your dependencies out loud.</strong> If someone is waiting on you, that&rsquo;s the first thing you do, not a line in a planning doc.</li>
<li><strong>Agree on names and shapes in writing before you start.</strong> It takes fifteen minutes.</li>
<li><strong>Write the first test early.</strong> Ours found two real bugs within minutes of existing.</li>
<li><strong>Test on a database that already has data in it.</strong> Empty is the one case that always works.</li>
<li><strong>Treat 100% as a warning, not a result.</strong> Measure the clever version before you keep it.</li>
<li><strong>Write your limitations while you build.</strong> It&rsquo;s the only time you actually remember what you decided not to handle.</li>
<li><strong>Don&rsquo;t let the writeup get ahead of the interface.</strong> A judge will open the app and check.</li>
</ul>
<h2 id="try-it">Try it</h2>
<ul>
<li><strong>Live demo:</strong> <a href="https://diresq.onrender.com">diresq.onrender.com</a>. Sign in as <code>londo</code> with the password <code>diresq</code>. It&rsquo;s on a free tier, so the first load can take about a minute to wake up.</li>
<li><strong>Demo video:</strong> <a href="https://youtu.be/T0Udg9WgRYA">YouTube</a></li>
<li><strong>Docs:</strong> <a href="https://skythe7.github.io/DiresQ">skythe7.github.io/DiresQ</a></li>
<li><strong>Code:</strong> <a href="https://github.com/Skythe7/DiresQ">github.com/Skythe7/DiresQ</a></li>
<li><strong>Devpost:</strong> <a href="https://devpost.com/software/diresq-8zjngi">DiresQ on Devpost</a></li>
</ul>
<p>Built by Skythe (frontend) and me (backend).</p>
<h2 id="closing-thought">Closing thought</h2>
<p>Back to that dispatcher&rsquo;s question: can we account for everyone?</p>
<p>With DiresQ, the answer is either yes, or a red row with a name, a last known position, and a report that&rsquo;s already been filed.</p>
<p>Nobody has to notice you went quiet.</p>
]]></content:encoded></item></channel></rss>