Day 1 of the Inventory Brain: What actually got done
I planned to build a beautiful app. I ended up with a working database, one API endpoint, and a form that submits without breaking. That's it. That's the win.
I started at 9am with a list of things I wanted to build: barcode scanning, category management, photo uploads, a search bar, a mobile-friendly layout, export to CSV...
By noon I had a Python virtualenv and a SQLite schema.
That's fine. That's actually exactly right.
What Day 1 is actually for
The goal of Day 1 isn't to have something impressive. It's to have something running. A database that holds data. A server that starts without errors. A form that writes to the database when you submit it.
Those three things take longer than you think, and they're the foundation for everything else.
My Day 1 checklist had exactly:
[ ] Python venv set up and activated
[ ] SQLite schema written (items table, minimal columns)
[ ] FastAPI app starts on localhost:8080
[ ] POST /items works (via curl or Postman)
[ ] Basic HTML form submits and writes to DB
[ ] You can see the item in the DB with sqlite3 CLI
I finished all of them. The form was ugly. The schema had no indexes. The FastAPI routes had no error handling. All of that is Day 2's problem.
The schema I ended up with
CREATE TABLE items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
location TEXT,
quantity INTEGER DEFAULT 1,
notes TEXT,
created_at TEXT DEFAULT (datetime('now'))
);
No categories. No barcodes. No photos. Just enough to prove the concept.
I'll add columns later. SQLite makes that easy. What I can't easily add later is "does the data model make sense for this problem" — so I spent 20 minutes just writing items on paper before touching the schema.
The FastAPI route that actually shipped
@app.post("/items", response_model=ItemOut)
async def create_item(item: ItemIn, db: AsyncConnection = Depends(get_db)):
cursor = await db.execute(
"INSERT INTO items (name, location, quantity, notes) VALUES (?, ?, ?, ?)",
(item.name, item.location, item.quantity, item.notes),
)
await db.commit()
return {**item.dict(), "id": cursor.lastrowid, "created_at": datetime.now().isoformat()}
That's it. No authentication. No pagination. No fancy error handling. It writes to SQLite and returns the created item.
What I skipped
- Didn't set up any UI framework beyond a plain HTML file with a form
- Didn't install Tailwind (Day 2)
- Didn't think about mobile
- Didn't add any tests (Day 3 maybe, realistically never for a local app)
The mindset that helps
On Day 1, every time you feel the urge to add something, write it on a sticky note instead. By end of day you'll have a pile of sticky notes and a working foundation. The sticky notes become Day 2's backlog.
The foundation is the thing. Everything else is optional.