whoevencares

Mambaul Hisam

Sun Jul 06 2025

Hacer!

We started this project 1 years ago when i was in the college with my friends as a final result on Programming Project course. A bit fun fact, in this course, we (the team) act like software engineers as in industries. In every week we do weekly stand up as a scrum routine, talking the progress, backlog refinement, or just brain storming.

We developed fully functional web system. The interaction between system and users is done by using Svelte as our front-end framework to develop user interface. But, in this writings, i gave more focus on back-end discussion like tech stack i use, features, and integration.

Tech Stack

As a back-end developer my self, in this project i use PostgreSQL Docker container, TypeScript, Node.js and Express.js. We agree to use REST API model for data communication between client and server at the beginning of this project, before we split up the team into back-end and front-end. With REST architecture, it's relatively easy to integrate with another system, specially web browser.

But,

Why PostgreSQL?

We, the team, agreed to use PostgreSQL with no particular reason. However, it's performant, reliable, with data integrity in mind. If you take a look on Recruitment Poster, PostgreSQL becomes one of industrial standard in database management system.

At the other side, we are working together as team and to ensure development environment consistency across platform, we utilize PostgreSQL's Docker image. The table scheme itself is relatively simple, with only 3 tables: holds user information; a list of user tasks; and a passive table that holds priority of the task.

TypeScript Hands-on

Me, personally haven't use TypeScript before. I tried JavaScript but it's felt weird for me. In my opinion, it's okay to use JavaScript in the browser, you don't have to worry about system crash after you doing "hacking". Because it's sandboxed by nature that browser's have. Or, it can be used when you think “i only need to run it in seconds and maybe i will need to run it again in the future”, that's the idea of a scripting language. Since then, i used to wrote this project using TypeScript as my hands-on experience.

The programming paradigm we use at the time of writing is object-oriented. The source directory in this project is divided into 3 parts, it similar to MVC architecture in full-stack development. But, the difference is, we use repository directory instead of view. In this directory contains database operation that performs queries to the database.

Runtime and Serving

There is no other choice at the time, we choose Node.js in-combination with Express.js to serve and receiving user's data. This back-end system has 11 end-point API. Each API perform CRUD operation. An exception on /user/signout, it's just remove the user's sessions Map from memory. According to popular opinion, what we call a back-end, is a system to acts as database wrapper that performs CRUD operation.

Features

This project have 2 main features:

  • CRUD operation to the tasks and users table
  • Third-party push notification

Integration

We utilize Telegram bot as push notification service, but the code is somewhere located. I forgot to push into GitHub. I have a proof that states the integration has done successfully. Look at this image:

integration-proof

The image was taken during testing time on this bot. To receive notification, you just need to login into system with colon separated username and password through bot. After you logged in, the bot push you a notification five minutes before the event automatically.

Present View

If we look at the code, i would like to say: this code is crap, how did i write this code like this?. Take an example this deep nested code. We can refactor it to something like this:

if (!res.data || res.data.length <= 0) {
  return {
    httpCode: 401,
    result: Results[Results.SignInFailed]
  };
}
if (!(res.data[0].uname && res.data[0].passwd && res.data[0].id)) {
  return {
    httpCode: 401,
    result: Results[Results.SignInFailed]
  };
}
if (reqObj.passwd === res.data[0].passwd) {
  let key = sessEncryption(
    res.data[0].id,
    res.data[0].uname
  );
  Sign.userSession.set(res.data[0].id, key);
  return {
    httpCode: 200,
    result: Results[Results.SignInSucceed],
    key: key
  };
}
return {
  httpCode: 406,
  result: Results[Results.MissingRequiredField]
};

Use early return for every condition statement, of course the refactored code boost readability and looks cleaner.

Another creep is here. I don't know why i wrote the query like that, but i assume if just INSERT statement at the time i didn't know if user_id didn't exist, it would fail. Look at the table definition of Checklists table, user_id has relation to the Users table. This means, i can perform insertion without selecting Users table. But, the problem is, we isolate the id of user from client, the server don't know user's id of current client and this is why do i do selection first to get the user id based on given username from client.

To solve the problem, we just gave the id of user to the client, if user adding task, the query can be simplified like this:

INSERT INTO CheckLists (subject, description, date, importance_id, user_id)
VALUES ($1, $2, $3, $4, $5)

As i discuss earlier, the database have a passive table, that holds priority of the tasks or checklists. What does passive table means? I used this words to describe a table with fixed rows of data and you can't adds more to it. Go to line 27, it say what i mean.

Discussing about database optimization, the table definition it self can be refactored into more optimal. We can drop the Importances table and change the Checklists table into this:

CREATE TABLE CheckLists (
    id UUID DEFAULT gen_random_uuid(),
    subject VARCHAR(100) NOT NULL,
    description VARCHAR(1000),
    date TIMESTAMPTZ NOT NULL,
    importance CHAR(10) NOT NULL CHECK (importance IN ('urgent', 'general')),
    user_id UUID,
    PRIMARY KEY (id),
    CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES Users(id)
);

With this modified table, you reduce the memory/storage footprint of the databases.

Conclusion

I learned a lot from this project, especially about TypeScript. I included this project as my back-end portfolio.