GoodWill-SmartSort
Track 3 · Goodwill Industries · Problem Statement 4: Rethinking Donation Systems for a Circular Economy
Android app that helps Goodwill-style networks prescreen donations, coordinate workers and shippers, and list resale for shoppers. It targets better intake, less unsuitable volume, and a smoother circular reuse loop.
Inspiration
Large reuse networks like Goodwill move enormous volumes of donated goods, yet a significant share of what arrives is not fit for resale, which drives expensive sorting and diversion work and uneven staffing when donation mix and volume swing by site and season. Donors also often guess what to bring, which increases mismatch between what shows up and what stores can sell or recycle efficiently.
We built GoodWill SmartSort to close the loop on the donation lifecycle: help people make better decisions at the point of donation, give staff clearer queues and routing, connect logistics so goods reach the sales floor when they should, and give shoppers access to approved resale after verification and delivery.
What it does
GoodWill SmartSort is an Android app (Jetpack Compose) with role-based experiences.
Donor
- Chooses category, optional age and notes, and one or more photos.
- On-device photo quality checks (blur, brightness, size) before cloud analysis.
- Google Gemini multimodal vision analysis → rule-based DecisionEngine → routing: resale, recycle, or disposal, with reasons and confidence.
- Batch (cart) by routing bucket, checkout with drop-off or pickup, tied to Goodwill-style locations (bundled catalog + nearby search via Photon / OpenStreetMap, with fallback).
- Support hub and voice-guided ticket filing.
- Voice help: scripted questions are spoken (ElevenLabs or on-device TTS); answers via speech-to-text; ticket saved for customer service.
Worker
- Pending queues including manual inspection when needed; open item, confirm or override AI routing, add notes.
- Location hub with store-scoped views when assignments apply.
Manager
- Dashboard stats, pending tasks, worker–store assignments, stock by site and placed batches, predictions views, worker correction tracking.
Shipper
- Lists worker-verified items awaiting “Delivered at Goodwill” once a site is assigned (e.g. after donor checkout). Confirms physical arrival; resale listings unlock for customers after this step (per app rules).
Customer
- Resale shop for items that are approved for resale and delivered; cart and checkout with shipping address; brownie-style rewards to donors on sale.
Customer service
- Views support tickets from donors.
How we built it
| Layer | Details |
|---|---|
| UI | Kotlin, Jetpack Compose, Navigation Compose, Material 3 |
| State | ViewModels, StateFlow, Coroutines |
| Persistence | Room (donations, baskets, orders, assignments, carts, purchases, tickets, …) |
| HTTP | OkHttp (Gemini, ElevenLabs, location APIs) |
| Images | Coil |
| Config | API keys via local.properties → BuildConfig |
Google Gemini
GeminiVisionAnalyzercalls the GeminigenerateContentREST API, modelgemini-2.5-flash.- Request: system instruction + user text (category, notes) + one or more images as inline JPEG base64.
- Prefers JSON-shaped output; fallback if JSON MIME handling fails; parsed into a structured VisionReport.
- Safety settings tuned for real donation photos.
DecisionEngineapplies deterministic policy after the model (resale / recycle / disposal).
ElevenLabs
ElevenLabsTtsClient: REST text-to-speech, modeleleven_multilingual_v2, returns MP3 bytes.DonorVoiceHelpViewModel: uses key and voice from BuildConfig; if key missing, on-device TTS speaks the same prompts.
Other
- Photon (Komoot) for nearby places; bundled Goodwill-style locations as fallback.
How this improves process and manual effort
- At intake: AI + rules give donors immediate resale / recycle / disposal guidance before drop-off, improving quality and relevance of donations.
- Before sorting: Photo quality gates reduce wasted review; AI-first triage focuses staff on exceptions; manual inspection handles edge cases.
- Across locations: Manager views and assignments help when volume and category mix fluctuate.
- Logistics: Shipper confirmation links physical arrival to shop eligibility for resale.
- Communication: Structured tickets and voice flow route issues clearly to customer service.
Net effect: less reactive sorting at the dock, more guided intake, targeted human review, and clear handoffs.
Challenges we ran into
- Messy photos and JSON parsing from vision (timeouts, output size, MIME retry paths).
- Safety filters on authentic donation images — mitigated with domain-specific settings.
- Encoding organizational policy in rules on top of probabilistic AI.
- One app, many roles — navigation and testing surface grows quickly.
- Keys in BuildConfig — developers must configure
local.propertiesand rebuild; keys must not be committed. - Keeping the demo story internally consistent end-to-end.
Accomplishments we're proud of
- A vertical slice: donate → Gemini + rules → worker → shipper → customer shop.
- Gemini 2.5 Flash for real multimodal screening, not a stub.
- ElevenLabs for natural spoken prompts in voice help, with TTS fallback.
- Room-backed, multi-role flows that feel like an operations sketch.
- Manager, worker, shipper, and customer surfaces that tell one coherent story.
What we learned
- AI for signals + code for policy matches how real ops teams think about risk.
- Physical steps (delivery) must be first-class in the product model.
- Voice helps donors; fallbacks help demos and development.
- Depth on one journey beats breadth of shallow features for hackathon impact.
What's next
- Richer donor education (accept lists, tips tied to screening outcomes).
- Clearer diversion paths with reuse / recycling partners.
- Backend, identity, and audit for production use.
- Metrics: override rates, time-to-decision, resale conversion.
- More languages and accessibility.
Login IDs & Passwords (demo / hackathon)
All credentials are demo-only, baked into the app for judging. Replace with a real auth backend for production.
| Role | User ID | Password | Notes |
|---|---|---|---|
| Donor | donor |
donor123 |
Default donor flow: donate, batch, checkout, support. |
| Worker | worker |
worker123 |
Same password for every worker account. |
| Worker | worker2 |
worker123 |
Second demo worker (e.g. different region assignment). |
| Worker | worker3 |
worker123 |
Third demo worker. |
| Manager | manager |
manager123 |
Dashboard, assignments, stocks, pending tasks, predictions. |
| Customer service | csagent |
csagent123 |
View donor support tickets. |
| Shipper | shipper |
shipper123 |
Confirm items delivered at Goodwill. |
| Customer | customer |
customer123 |
Browse resale shop, cart, purchase. |
Worker reminder: choose role Worker, then sign in with worker, worker2, or worker3 — password is always worker123.
Security: do not treat these as secrets; they are for local/demo use only. Never reuse demo passwords for real accounts.
Setup & API keys
Add to local.properties at the project root (this file is gitignored), then Rebuild Project:
GEMINI_API_KEY=your_key_here
ELEVENLABS_API_KEY=your_key_here
ELEVENLABS_VOICE_ID=your_voice_id_optional
Build
From the project root:
./gradlew :app:assembleDebug
Debug APK output: app/build/outputs/apk/debug/app-debug.apk
Links (optional)
- Repository: GoodWill-SmartSort on GitHub
Log in or sign up for Devpost to join the conversation.