Inspiration

Most of us grow up hearing one clear message: “Just say no to drugs.” That message is well‑intentioned, but it leaves a gap: people we care about still say “yes” — quietly — with almost no access to honest, practical safety information.

We took inspiration from harm‑reduction work like DanceSafe and from the way sex education slowly evolved. For sex, the world moved (painfully) from “don’t do it” to “if you’re going to, here’s how to reduce risk.” We felt drug use deserves the same honesty. Our friends, classmates, and peers are already experimenting; pretending otherwise doesn’t keep them safe.

That led to the central idea behind If You Say Yes:

Most of us have been taught to say “no” to drugs since childhood, but when harmless‑looking things are sold as ways to feel happier, smarter, or better, what prepares us for the moment that “no” turns into a “yes”?

We wanted a project that doesn’t glorify drugs, but that treats people who use them as adults who deserve accurate information, safer options, and tools to understand risk. We also want to create a community where people can share about their own experience.

What it does

If You Say Yes is a harm‑reduction web app that focuses on three core workflows:

Drug–drug interaction checker (Phase 1): Lets you select two substances and quickly see:

  • A risk level: Unknown / Low / Caution / Dangerous.
  • A short, plain‑language mechanism description (e.g. enzyme inhibition, bleeding risk).
  • Results are backed by a Neo4j graph of Substance nodes and [:INTERACTS_WITH] relationships. Substance profile dashboard (Phase 2):
  • A clinical‑style grid of cards for each substance, showing:
    • Half‑life, bioavailability, standard dosage.
    • Optional “dosage summary” and top adverse events (from structured JSON fields).
    • Community comments, where people can share observations, questions, or context about a substance while we clearly separate that from the structured reference data.
    • The dashboard is powered by a Spring Boot + PostgreSQL API and rendered in a Next.js dashboard. Reagent test assistant (Phase 4):
  • Accepts a photo of a reagent test plus optional context. -Uses a vision model to:
    • Extract dominant reagent colors (hex values).
    • Suggest substances that best match those colors, with relative probabilities.
    • Presents the output as a chat‑style explanation with a horizontal bar chart and a very explicit disclaimer that colorimetric testing is presumptive and cannot “prove” what a substance is.
    • Across all three, the UI is designed to feel like a serious tool, not a toy: calm typography, clear hierarchy, and a consistent theme that highlights risk without sensationalism.

How we built it

We split If You Say Yes into a few focused services that work together:

  • Python FastAPI backend (Phase 1 – interactions + reagent analysis) We built a FastAPI service that:
    • Exposes GET /interaction to answer questions like “What happens if I mix A and B?”.
    • Connects to a Neo4j Aura graph, where we model drugs as Substance nodes and relationships as [:INTERACTS_WITH { risk_level, mechanism, inferred, ... }].
    • Exposes POST /reagent/analyze, which accepts reagent test images, calls a vision model to extract hex colors, and then maps those to likely substances.
  • Java Spring Boot core-api (Phase 2 – substance profiles) In parallel, we built a Spring Boot service backed by PostgreSQL:
    • JPA entities like SubstanceProfile store structured data: half-life, bioavailability, standard dosage, classification, adverse events, etc.
    • A REST endpoint GET /api/substances returns paginated lists for the dashboard.
    • This is the “clinical reference” side of the project.
  • Two databases, one combined view Concretely, the app uses two databases:
    • Neo4j Aura for interaction relationships (who interacts with whom, and how risky that is).
    • PostgreSQL for per-substance information (what the drug is like on its own). On the frontend, we pull from both: Neo4j via FastAPI for interaction answers, and Postgres via core-api for rich profiles. The UI stitches these together so users don’t have to mentally combine data from multiple tools.
  • Next.js frontend (shared template for Home, Dashboard, Reagent) We used the App Router in Next.js to build:
    • A shared layout.tsx that provides a gradient red/pink background, a serious header (“If You Say Yes”) and a consistent nav (“Home”, “Dashboard”, “Reagent test”).
    • A home page that: Explains the project’s harm-reduction goal. Embeds a client-side DrugInteractionForm wired to the FastAPI backend. Introduces the risk-level system and the dashboard.
    • A dashboard page (/dashboard) that uses a client component (DashboardClient) to fetch from core-api, normalize some messy JSON fields, and render substance cards in a grid. Users can also leave comments, which live alongside the structured data but are clearly separated from it.
    • A reagent test page (/reagent) that uses a chat-like React component to handle image uploads, show analysis from the vision backend, and visualize match probabilities as horizontal bar charts.
  • Infrastructure and developer experience We wired everything together with:
    • Environment variables (NEO4J_URI, OPENAI_API_KEY, NEXT_PUBLIC_*) so the same code runs locally and in Docker. docker compose to spin up Postgres, core-api, frontend, and optionally the Python backend in one command.
    • Clear health endpoints (/health in FastAPI, GET /api/substances in core-api) and verbose error messages so it’s obvious when a database or API key is missing.

Challenges we ran into

Balancing tone: not glamorizing, not shaming

  • Writing copy that is non-judgmental but very clear about risk was harder than expected.
  • We iterated on the tagline and on in-UI wording to avoid sounding like a product demo for drugs, while still being honest and useful.

Making safety logic explainable

  • Graph-based interactions can be subtle.
  • Mapping that nuance into a simple color-coded card (Low / Caution / Dangerous) without over-promising took work.
  • We added a no_known_effect flag and text like “does not guarantee safety” to be transparent about data limits.

Heterogeneous stack

  • Coordinating Python + Neo4j, Java + Postgres, and Next.js created friction around:
    • Environment variables.
    • Local vs Docker networking.
    • Consistent error handling and timeouts.
  • We invested in a clear README and health endpoints to reduce confusion.

Vision + reagent testing

  • Reagent testing in the real world is noisy:
    • Lighting, camera quality, and mixed reagents all affect color.
  • We had to:
    • Cap image size.
    • Add very explicit errors for missing OPENAI_API_KEY.
    • Normalize legacy and new vision responses into one shape for the UI.

Accomplishments that we're proud of

End-to-end harm-reduction experience

  • From “What happens if I mix these?” to “What does this reagent color mean?” to “What’s the half-life on this?”, the app addresses real questions people have but often feel unsafe asking.

Clear, defensive error handling

  • Instead of generic 500s, the API returns:
    • “Neo4j is not available…”
    • “Interaction service not configured…”
    • “OPENAI_API_KEY is not set…”
  • The UI surfaces these as friendly alerts instead of blank screens.

A UI that doesn’t talk down to users

  • No cartoon mascots, no jokes about getting high — just honest, calm, grown-up information.
  • The layout makes the purpose of the app clear without sensational imagery. ## What we learned Harm reduction is as much about language as it is about code.
  • A single sentence can change how people interpret the whole project.
  • We spent almost as much time on wording as on some backend pieces.

Graphs are natural for interaction modeling.

  • Neo4j made it easier to think about relationships between substances, potential “relative” interactions, and future expansion (e.g. multi-drug combinations or shared mechanisms).

Consistency across a multi-service stack reduces cognitive load.

  • Shared conventions (JSON shapes, pagination patterns, environment variable names) made it far easier to swap backends or refactor the frontend.

Users need both “headline” answers and detail.

  • Color-coded risk is good as a headline, but serious users also want:
    • Mechanism.
    • Context like half-life or bioavailability.
    • Caveats and disclaimers.
  • Designing for both quick scans and deep reading was a useful design exercise.

What's next for If you say 'Yes'

Richer data sources and citations

  • Add inline citations so users can see exactly where a given risk level comes from.

Personalized risk context

  • Carefully, and always anonymized, incorporate simple user-provided factors (e.g. known medications) to highlight more relevant interactions — always with clear limits and warnings.

Safer workflows on mobile

  • Optimize the UI for low-light, on-site use at festivals and nightlife venues, where phones and bandwidth are limited.

Better reagent guidance

  • Add more reagent types, known color charts, and clearer guidance on what cannot be concluded from a single test.
  • Explore simple math models for interpolating confidence: $[ \text{confidence} \approx \frac{1}{Z}\exp\left(-\frac{\lVert c_{\text{observed}} - c_{\text{reference}}\rVert^2}{2\sigma^2}\right) ]$ where $(c)$ is a color vector and $(\sigma)$ captures uncertainty.

Community feedback loops

  • Allow harm-reduction org staff to suggest corrections or improvements, and potentially integrate with existing resources like drug-checking services and vetted educational materials.

Ultimately, the goal is not to convince anyone to say “yes” — it’s to recognize that some people already do, and to make sure that when they do, they’re not walking in blind.

Built With

  • and-neo4j?python?driver)-connected-to-neo4j-aura-for-the-interaction-graph-and-to-the-openai-vision-api-for-reagent-image-analysis;-a-java-spring-boot-core-api-using-spring-web
  • and-postgresql-for-structured-substance-profiles;-and-a-next.js-(react-+-typescript)-frontend-styled-with-tailwind-css-that-talks-to-both-backends-via-rest.-we-manage-the-environment-and-local-development-with-docker-/-docker-compose
  • docker
  • fastapi
  • java
  • javascript
  • jpa
  • neo4j
  • next.js
  • node.js
  • node.js/npm
  • npm
  • openaiapi
  • postgresql
  • pydantic
  • python
  • spring-data-jpa
  • springboot
  • tailwind
  • typescript
  • uvicorn
Share this project:

Updates