About MedConnect
Tagline: Notice how you feel. Find what helps. Connect with people who understand.
GitHub: https://github.com/crispychip146/medconnect-sdg3
Generated presentation: https://www.presentmeapp.xyz/p/37e0f0b3-71cf-4d35-8309-d80ce4a00eeb
Inspiration
Mental health is half of well-being — yet most consumer health apps focus on the physical
side. The World Health Organization estimates that 970 million people live with a mental
health condition worldwide, and more than 70% of countries have fewer than one psychiatrist
per 100,000 people. That gap — between the scale of the need and the availability of
professional care — is what MedConnect was built for.
I wanted to create something that could actually help someone tonight, not just in a perfect
scenario where they've found a therapist they can afford. That meant three things had to be
true: it had to be free, it had to work without a professional involved, and it had to feel
like a community, not a clinical tool.
What it does
MedConnect is a Flask web app with five integrated features:
- Mood tracking — A daily 1–10 check-in with a 14-day line chart. Patterns become visible
without judgment. - Peer support forum — Six categories (anxiety, depression, self-care, support, success
stories, and general). Every post and comment can be posted anonymously. - Guided wellness exercises — An animated 4-4-4-4 box-breathing circle plus tracking for
gratitude, grounding, and body-scan practice. Includes a daily streak counter. - Curated resource library — Real-URL-only links to hotlines (988, SAMHSA, Crisis Text Line,
Find A Helpline), articles (WHO, NHS, NIMH, Mind, Mental Health Foundation, Verywell Mind),
and apps (Headspace, Calm, Insight Timer, 7 Cups, TalkLife).
- Crisis help — A dedicated, visually-distinct page that surfaces 24/7 crisis hotlines one
tap away from anywhere in the app.
How I built it
Stack: Flask, Flask-SQLAlchemy, SQLite, vanilla CSS, a sprinkle of JavaScript. Chart.js for the mood chart via CDN. No build step, no node_modules, no API keys.
Architecture — strict MVC layout:
medconnect/
├── app.py # Flask entry point
├── config.py # Reads DATABASE_URL env var, falls back to SQLite
├── models/ # SQLAlchemy: User, Mood, Post, Comment, Resource, WellnessCheckin
├── controllers/ # Business logic per feature
├── routes/ # Blueprint routes (auth, mood, forum, resources, wellness)
├── templates/ # Jinja2 templates (base + 11 pages)
├── static/css, js/ # Hand-written CSS design system, no framework
├── utils/seed_data.py # 18 real orgs + 7 demo posts + 4 personas
└── instance/medconnect.db # Auto-created on first run
UI — I designed a "soft clinical wellness" system: Instrument Serif for display, Inter for
body, JetBrains Mono for data. The signature element is a mood ribbon — a spectrum gradient
from slate (low) through teal (neutral) to peach (high) — that ties the home page, breathing
stage, and chart together. Every icon is hand-coded SVG; no emoji icons.
Database — SQLite by default (medconnect.db auto-created on first run). For deployments, the app honors a DATABASE_URL env var so it can swap to Postgres or MySQL with zero code changes.
Testing — 45 in-process tests covering auth, mood validation, forum CRUD (anon + named), wellness streak logic, chart series, resource filtering, and input validation. All pass.
Challenges I faced
- Detached SQLAlchemy sessions: My first attempt passed post objects across with
app.app_context() blocks, and display_author lazy-loaded author usernames that crashed with
DetachedInstanceError. Fixed by adding joinedload(Post.author) everywhere forum posts cross
app-context boundaries. - Jinja's any filter doesn't exist: I tried chart_scores|any in a template — Jinja doesn't
have one. Moved the truthy check into the controller. - The "every URL must work" requirement: A few seeded resources had placeholder URLs or dead
links. I audited every resource against real organizations, replaced broken ones (like
calmharm.co.uk) with working equivalents (mentalhealth.org.uk, psychologytools.com,
findahelpline.com), and verified each one resolves. - Crisis UX got right: Crisis resources needed to be visible without searching — they're in
the top nav, on every page footer, and on their own dedicated page with a red-striped visual treatment. If you scroll to the bottom of any page on MedConnect, there's always a way out. - Database connection question: I had to clarify for myself that SQLite is a real database —
it doesn't need a server, but it persists data to a file and supports real SQL queries. Built
a config layer that lets users swap to Postgres by setting one env var.
What I learned
- A signature design element matters more than fancy components. The mood ribbon — a single
gradient — does more for brand identity than ten micro-interactions would. - Crisis UX is design with stakes. Designing for "what if someone is reading this at 2am in
crisis" forced choices I wouldn't otherwise have made: hotline numbers in footers, a
red-striped visual treatment, no dark patterns, no upsells. - Test the seams, not the units. The two real bugs I shipped (DetachedInstanceError and the
missing Jinja filter) both lived at integration boundaries — between SQLAlchemy and Flask
context, between controller and template. They wouldn't have appeared in unit tests. - Anonymous-by-default is hard; anonymous-as-an-option is easy and just as protective. Posts
default to "show your username" but let users opt into anonymity per-post. This keeps the
community feeling real while giving privacy to people who need it.
What's next
- OAuth login (Google, Apple) so people don't need yet another password
- Optional therapist directory per region
- Mobile PWA install so it feels at home on a phone
- Export mood data to CSV for users who want to share it with their actual therapist
Log in or sign up for Devpost to join the conversation.