Skip to main content

Command Palette

Search for a command to run...

From Data to Code: Modeling EventHive

Published
•5 min read•View as Markdown
S

Junior Developer exploring full-stack development, backend systems, and cloud deployment. Breaking code, bending logic, and sharing secrets devs weren’t supposed to see. React | Spring Boot | Go | Python | MongoDB | SQL | Networking. Check out my GitHub and blog for projects and experiments!

Up to now, we’ve spent time thinking instead of typing.

We talked about:

  • who the users are

  • what the system stores

  • how users and events are connected

That work wasn’t theoretical.
It was preparation.

Because now, when we open a code editor, we’re not guessing what to build.
We’re simply giving form to ideas we already understand.

This post is where that happens.

Not signup.
Not login.
Not APIs.

Just models and relationships, written calmly and intentionally.


The Project Structure (Exactly What We’ll Use)

Before writing any code, let’s look at where things live.

eventhive/
│
├── README.md
├── requirements.txt
├── SETUP.md
│
└── src/
    │
    ├── app.py
    │
    ├── config/
    │   └── database.py
    │
    └── models/
        ├── user.py
        ├── event.py
        └── __init__.py

This structure is doing quiet but important work.

  • Everything that runs lives inside src

  • Configuration is separated from meaning

  • Models are grouped by what they represent, not by features

If you understand this layout, the backend already feels less intimidating.


A Note About the GitHub Repository

I’m maintaining a GitHub repository alongside this series.

Each blog post corresponds to a clean commit that contains only what we’ve discussed so far.

Post 3 introduces:

  • a minimal Flask app

  • database connection

  • user and event models

Nothing more.

You don’t need the repo to follow along —
but it’s there if you want a stable reference point.


Dependencies (requirements.txt)

We’re keeping this intentionally small.

flask
pymongo
python-dotenv

No frameworks layered on frameworks.
No abstractions we can’t explain yet.

Just enough to run a backend and store data.


Database Connection (src/config/database.py)

The database connection is infrastructure.

It should exist in one place, and one place only.

from pymongo import MongoClient
import os

client = MongoClient(os.getenv("MONGO_URI"))
db = client["eventhive"]

This file doesn’t contain logic.
It doesn’t know about users or events.

It simply says:

“Here is the database. Use it.”

Later, every model will depend on this — and that’s exactly how it should be.


Minimal Flask App (src/app.py)

Right now, Flask’s job is modest.

It just needs to exist and prove that everything is wired correctly.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return {"status": "EventHive backend running"}

If this runs, we know:

  • Flask is set up correctly

  • the project structure works

  • we’re ready to build on top of it

That’s enough for now.


The User Model (src/models/user.py)

Let’s bring back the question we asked in the previous post:

What do we need to remember about a user?

Nothing new has appeared since then.

A user still has:

  • a name

  • an email

  • a password (hashed later)

  • a role

  • a creation timestamp

Now we translate that thinking into code.

from datetime import datetime
from config.database import db

class User:
    def __init__(self, name, email, password, role="attendee"):
        self.name = name
        self.email = email
        self.password = password
        self.role = role
        self.created_at = datetime.utcnow()

    def to_dict(self):
        return {
            "name": self.name,
            "email": self.email,
            "password": self.password,
            "role": self.role,
            "created_at": self.created_at
        }

    def save(self):
        return db.users.insert_one(self.to_dict())

There’s nothing clever here.

And that’s the point.

The code mirrors the idea exactly.

If you ever feel unsure about a model, the problem usually isn’t Flask —
it’s that the idea itself wasn’t clear yet.


The Event Model (src/models/event.py)

Events are where relationships show up.

from datetime import datetime
from config.database import db

class Event:
    def __init__(self, title, description, date, location, created_by):
        self.title = title
        self.description = description
        self.date = date
        self.location = location
        self.created_by = created_by
        self.attendees = []
        self.created_at = datetime.utcnow()

    def to_dict(self):
        return {
            "title": self.title,
            "description": self.description,
            "date": self.date,
            "location": self.location,
            "created_by": self.created_by,
            "attendees": self.attendees,
            "created_at": self.created_at
        }

    def save(self):
        return db.events.insert_one(self.to_dict())

Two fields matter more than the rest:

  • created_by

  • attendees

These fields don’t store full users.

They store references.

And that’s enough.


Relationships

Let’s avoid database terminology for a moment.

  • One user can create many events

  • One event is created by one user

That’s why created_by stores a user ID.

Now:

  • One event can have many attendees

  • One user can attend many events

That’s why attendees is a list of user IDs.

No joins.
No embedding entire documents.
No hidden complexity.

Just clear references.

And this matters more than it looks.


Where Relationships Actually Belong

Here’s a subtle but important idea:

👉 Relationships belong in the data, not in the routes.

Routes will later use these relationships:

  • to check permissions

  • to enforce ownership

  • to decide what actions are allowed

But they don’t define them.

This separation keeps the system understandable as it grows.


What We’ve Done (Before Any Features)

At this point:

  • the backend exists

  • Flask is running

  • MongoDB is connected

  • users have a real shape

  • events have a real shape

  • relationships are intentional and visible

And notice something important:

We still haven’t talked about authentication.

Yet.

Because now, when we do, it will feel obvious — not overwhelming.


What Comes Next

Users exist.
Events exist.
The system knows how they relate.

Now we can finally ask:

How does a user prove who they are?

That’s where signup and login belong.

Not earlier.
Not randomly.

➡️ Next Post: Authentication Built on Real Models

And this time, it won’t feel rushed.

It’ll feel earned.

From Requirements to Real Systems

Part 3 of 3

In this series, we build a real-world application step by step—starting from requirements, not code. We learn how engineers think: understanding problems, designing systems, modeling data, and then writing code that actually makes sense.

Start from the beginning

Why Are We Starting This Series?

Have you ever felt like building an application from scratch? Not just following a tutorial — but actually building something on your own. You can write code.You can follow step-by-step guides.Yet when you stare at a blank project folder, everything ...