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:

  1. Mood tracking — A daily 1–10 check-in with a 14-day line chart. Patterns become visible
    without judgment.
  2. Peer support forum — Six categories (anxiety, depression, self-care, support, success
    stories, and general). Every post and comment can be posted anonymously.
  3. 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.
  4. 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).
  5. 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

Built With

Share this project:

Updates