favicon here hometagsblogmicrobio cvtech cvgpg keys

Part 1: So I am building a fullstack project

#mercado-series #rust #typescript #deno #fresh #fullstack

Soc Virnyl Estela | 2026-02-12 | reading time: ~4min

I noticed that I haven't challenged myself in building a fullstack project, let alone I have any experience integrating third-party payment APIs such as Stripe, and OAuth2.

So in this project, mercado. We will not be using LLMs or any coding agents in this endeavour. The only time I'll be using is maybe for repetitive tasks and for documentation.

"This is a series"§

Yes, writing this as a full blog post will take a while because I'll be scaffolding and building this project and might even refactor many times. Instead, I will write a separate posts from Part 1 until I consider it completed. I call this series as "So I am building a fullstack project", also known as Mercado Series because it's the name of the repo and project.

Why are you doing this?§

Cause, I noticed that I've been stagnating as well? I mean, I have learnt many things from my last jobs and I think it's high time to test out my skills again that I've gained and also challenge myself to build different projects for a Full Stack Developer skill.

Chosen technologies§

In this project, I'll be using Rust for the backend and Deno+Fresh for the frontend. Why not React? Because I already have experience writing with React. Not saying I am a master of it, but I can definitely write React and learn anything from blogs or YouTube. However, I am quite curious about Fresh and why the Deno team made it when there are already existing solutions.

I could have used Golang, but that would be for another fullstack project series.

Initial project structure§

I am following a monorepo style with the initial project structure below (dropdown)

Initial project structure
.
├── backend
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── Cargo.lock
├── Cargo.toml
├── crates
│   ├── api
│   │   ├── Cargo.toml
│   │   └── src
│   │       └── lib.rs
│   ├── auth
│   │   ├── Cargo.toml
│   │   └── src
│   │       └── lib.rs
│   ├── database
│   │   ├── Cargo.toml
│   │   └── src
│   │       └── lib.rs
│   └── payments
│       ├── Cargo.toml
│       └── src
│           └── lib.rs
├── frontend
│   ├── assets
│   │   └── styles.css
│   ├── client.ts
│   ├── components
│   │   └── Button.tsx
│   ├── deno.json
│   ├── deno.lock
│   ├── islands
│   │   └── Counter.tsx
│   ├── main.ts
│   ├── README.md
│   ├── routes
│   │   ├── _app.tsx
│   │   ├── api
│   │   │   └── [name].tsx
│   │   └── index.tsx
│   ├── static
│   │   ├── favicon.ico
│   │   └── logo.svg
│   ├── utils.ts
│   └── vite.config.ts
├── justfile
├── LICENCE
└── README.md

19 directories, 30 files

Defining the project§

Since this project is about some webapp that can be deployed over the internet, I need to determine the goals and intention of the project. Obviously, one is for learning. But the rest are unknown.

So it's an ecommerce app. Therefore, we need to specify what kind of products we sell, and what kind of sellers we have on the platform. Given the name of the project, I guess I can think of

  • fashion
    • clothing
    • shoes
    • accessories
  • food
    • ingredients
    • snacks
  • technology
    • computer parts
    • prebuilt desktops
    • laptops

The categories can still be extended. But for now, let's focus on those. Now I can imagine if I were to create a database table schema for these products then it would look like the SQL below

CREATE TABLE products (
	product_id uuid PRIMARY KEY,
	category INTEGER NOT NULL,
	product_name TEXT NOT NULL,
	currency VARCHAR(3) NOT NULL,
	price NUMERIC(12, 2),
	description TEXT DEFAULT NULL,
	created_at TIMESTAMP DEFAULT NOW(),
	updated_at TIMESTAMP DEFAULT NOW()
)

For users, we need to have some sort of categorisation as well. They can be

  • sellers
  • customers/subscribers
  • admins
  • guests

And the following tables can be created like this

CREATE TABLE users (
	id uuid PRIMARY KEY,
	category INTEGER NOT NULL,
	first_name TEXT DEFAULT NULL,
	last_name TEXT DEFAULT NULL,
	email TEXT NOT NULL,
	created_at TIMESTAMP DEFAULT NOW(),
	updated_at TIMESTAMP DEFAULT NOW()
	CONSTRAINT unique_email UNIQUE (email)
);

CREATE TABLE user_passwords (
    id uuid PRIMARY KEY,
    user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    password_hash TEXT NOT NULL,
    salt TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    UNIQUE(user_id)  -- ensures only one current password per user
);

I was thinking of using SERIAL or INTEGER for ID generation but in this small application, I don't think it's that important. I have yet to read or understand the performance implications but for now, I am focusing on the fact that each ID is guaranteed to be unique.

OAuth2? Let's focus for now the regular login. We'll add OAuth2 later once almost everything has been finalised.

How about usernames? I don't think they're important. email addresses are already unique on their own. But I can add them if that's really an impactful change.

Adding the database dependencies§

The file at crates/database/Cargo.toml contains the following

[package]
name = "database"
version = "0.1.0"
edition = "2024"

[dependencies]
deadpool-postgres = { version = "0.14.1", features = ["serde"] }
tokio = { version = "1.49.0", features = ["full"] }

With the following initial structure

.
├── Cargo.toml
└── src
    ├── core.rs
    ├── lib.rs
    ├── models
    │   └── mod.rs
    ├── prelude.rs
    └── utils
        └── mod.rs

4 directories, 6 files

The models will contain the table definitions, and utils will contain common functions that are used around.

core will encapsulate essential logic, and prelude will be used to import all commonly imported public namespaces.

To be continued§

This post will be continued the following day or week as I have other things to attend called life. See you in the next post.

Articles from blogs I follow around the net

[WFD 23] ipd adjustment and vomiting

i set the IPD wrong on my new Meta Quest 3 and spent the day wanting to throw up. turns out measuring your eyes properly matters.

via Ryana May Que — Writings for DiscussionFebruary 12, 2026

On Discord Alternatives

Next month, Discord is going to start requiring age verification. The backlash from gamers everywhere has been predictable and justified. I guess their company name checks out. I’ve had a few people reach out to me because of my prior vulnerability disclos…

via Dhole MomentsFebruary 11, 2026

2026-01-14: The Day the telnet Died

A long, long time ago I can still remember how a protocol used to make me smile And I knew if I had my chance That I could make those botnets dance And maybe they'd be happy for a while But January made me shiver With every packet I tried to deliver Bad n…

via GreyNoise LabsFebruary 10, 2026

Recently

ListeningDie In Love by Greet DeathVia David Crespo, I got into Greet Death, a band that's been hustling since 2011. It's great in a simultaneously familiar and innovative way. The album has a great amount of variety: Small Town Cemetery is a really effect…

via macwright.comFebruary 03, 2026

The role of the Software Engineer in the age of AI

Introduction For the last year or so, I’ve started using AI tools like ChatGPT and GitHub Copilot to help me with my software engineering tasks. For most of the time, these tools have been a great help. GitHub Copilot has helped me automate boilerplate…

via Christian Visintin BlogFebruary 01, 2026

The cults of TDD and GenAI

I’ve gotten a lot of flack throughout my career over my disdain towards test-driven development (TDD). I have met a lot of people who swear by it! And, I have also met a lot of people who insisted that I adopt it, too, often with the implied threat of appe…

via Drew DeVault's blogJanuary 29, 2026

2025 in review

Come along with me as I review the past year. Heh, I often start these kinds of posts right at the start of the year, but it takes a few weeks longer than I ever expect to think them through.1 Two years of being independent After a second year of operati…

via seanmonstarJanuary 27, 2026

The Birthday Paradox, simulated

I'm a fan of simulating counterintuitive statistics. I recently did this with the Monty Hall problem and I really enjoyed how it turned out. A similarly interesting statistical puzzle is the birthday paradox: you only need to get 23 people in a room a room…

via pcloadletterJanuary 23, 2026

Status update, January 2026

Hi! Last week I’ve released Goguma v0.9! This new version brings a lot of niceties, see the release notes for more details. New since last month are audio previews implemented by delthas, images for users, channels & networks, and usage hints when typing a…

via emersionJanuary 21, 2026

The Only Two Markup Languages

There are only two families of proper arbitrary markup languages: TeX and SGML I would normally link to official thing as reference but it's behind the "wonderful" ISO paywall: ISO 8879:1986.. By arbitrary, I mean the grammar specifically, and how it can …

via gingerBill - ArticlesJanuary 19, 2026

Gbyte leaks gigabytes of data - #FuckStalkerware pt. 8

plus an MMO boosting service, fully remote Android spying and patented ToS violations

via maia blogJanuary 06, 2026

Whiplash and the ideas of success

Some ideas about success and analysis of some of the concepts of the film Whiplash

via Ishan WritesJanuary 04, 2026

Merry Christmas, Ya Filthy Animals (2025)

It’s my last day of writing for the year, so I’m going to try keep this one quick – it was knocked out over three hours, so I hope you can forgive me if it’s a bit clumsier than my usual writing. For some strange reason, one of the few clear memories I hav…

via LudicityDecember 27, 2025

Why are people migrating away from GitHub?

I noticed some people migrating away from GitHub recently. I was curious to understand the rationale. Is it a blip or is it a sign of prolonged exodus?

via Rob O'Leary | BlogDecember 22, 2025

Yep, Passkeys Still Have Problems

It's now late into 2025, and just over a year since I wrote my last post on Passkeys. The prevailing dialogue that I see from thought leaders is "addressing common misconceptions" around Passkeys, the implication being that "you just don't understand it co…

via Firstyear's blog-a-logDecember 17, 2025

Testing multiple versions of Python in parallel

Daniel Roy Greenfeld wrote about how to test your code for multiple versions of Python using `uv`. I follow up with a small improvement to the Makefile.

via Technically PersonalJuly 21, 2025

LLDB's TypeSystems Part 2: PDB

In my previous post, I described implementing PDB parsing as a can of worms. That might have been a bit of an understatement. PDB has been one "oh, it's gonna be twice as much work as I thought" after another. Implementing it has revealed many of the same …

via Cracking the ShellJuly 07, 2025

#Rx Writing Challenge 2025

This is a short reflection on my experience of the recent writing challenge I took part in. Over the past two weeks, I have participated in the #RxWritingChallenge 1—a daily, 30-minute writing group starting at 9 AM every morning. Surrounded by fellow doct…

via Ul-lingaApril 05, 2025

Generated by openring-rs

favicon here hometagsblogmicrobio cvtech cvgpg keys