idris-taskapi adalah backend service untuk aplikasi manajemen task / to-do list. Aplikasi ini menyediakan REST API yang bisa dipakai oleh frontend apa pun — web, mobile, atau desktop — untuk membuat, mengatur, dan melacak daftar pekerjaan harian secara terstruktur.
Setiap user punya akun dan daftar task-nya sendiri yang terisolasi. Task bisa diberi judul, deskripsi, dan status pengerjaan (pending → in_progress → done), sehingga user bisa tahu mana yang sudah selesai dan mana yang masih perlu dikerjakan.
Aplikasi ini cocok digunakan sebagai:
- Backend untuk aplikasi to-do list — tinggal hubungkan ke frontend pilihan kamu (React, Vue, Flutter, dll.)
- Starter project — fondasi siap pakai untuk membangun aplikasi produktivitas yang lebih kompleks
- Bahan belajar — contoh nyata cara membangun REST API dengan autentikasi JWT, relational database, dan struktur MVC yang rapi
- Autentikasi aman — password di-hash dengan bcrypt, sesi dikelola via JWT tanpa menyimpan state di server
- Data terisolasi per user — setiap user hanya bisa melihat dan mengubah task miliknya sendiri
- Ringan dan cepat — dependensi minimal, tidak ada framework berat
- Mudah di-deploy — siap jalan di Render (free tier) dengan PostgreSQL managed, atau lokal via Docker Compose
- Arsitektur bersih — kode terpisah jelas antara routes, controllers, models, dan middleware; mudah dikembangkan
| Pengguna | Kegunaan |
|---|---|
| Frontend developer | Pakai sebagai backend siap pakai untuk project todo app atau task manager |
| Pelajar / mahasiswa | Pelajari cara kerja REST API, JWT auth, dan PostgreSQL dalam project nyata |
| Developer yang mau extend | Jadikan boilerplate — tambah fitur label, due date, tim, dll. sesuai kebutuhan |
| Recruiter / interviewer | Lihat contoh nyata kemampuan desain API, auth, dan database schema |
| Komponen | Teknologi |
|---|---|
| Runtime | Node.js |
| Framework | Express.js |
| Database | PostgreSQL 16 |
| Auth | JWT (jsonwebtoken) |
| Password hashing | bcrypt |
| DB driver | pg |
cp .env.example .env
# Edit .env — wajib isi JWT_SECRET dengan string random yang panjang
docker compose up -d # jalankan PostgreSQL di localhost:5432
npm install
npm run migrate # buat tabel users dan tasks
npm run dev # server berjalan di http://localhost:3000| Variable | Wajib | Default | Keterangan |
|---|---|---|---|
PORT |
3000 |
Port server | |
DATABASE_URL |
Ya | — | PostgreSQL connection string |
JWT_SECRET |
Ya | — | Secret key untuk signing JWT |
JWT_EXPIRES_IN |
1d |
Durasi token JWT |
Postman collection tersedia di postman/. Import idris-taskapi.postman_collection.json dan idris-taskapi.postman_environment.json, pilih environment idris-taskapi (local), lalu jalankan Auth → Register atau Auth → Login — token JWT tersimpan otomatis ke variabel {{token}} dan dipakai di semua request Tasks.
GET /health
→ { "status": "ok" }
| Method | Path | Keterangan |
|---|---|---|
| POST | /auth/register |
Daftar akun baru |
| POST | /auth/login |
Login, dapat JWT token |
# Register
curl -X POST http://localhost:3000/auth/register \
-H 'Content-Type: application/json' \
-d '{"email":"jane@example.com","password":"secret123"}'
# Login
curl -X POST http://localhost:3000/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"jane@example.com","password":"secret123"}'Gunakan token dari response sebagai Bearer token di semua request Tasks.
Semua endpoint task memerlukan header Authorization: Bearer <token>.
| Method | Path | Keterangan |
|---|---|---|
| POST | /tasks |
Buat task baru |
| GET | /tasks |
List semua task (opsional ?status=) |
| GET | /tasks/:id |
Detail satu task |
| PATCH | /tasks/:id |
Update title / description / status / priority / labels |
| PATCH | /tasks/reorder |
Atur ulang urutan seluruh task milik user |
| DELETE | /tasks/:id |
Hapus task |
status menerima nilai: pending, in_progress, atau done.
priority menerima nilai: low, medium, atau high. Opsional saat membuat task — default medium.
due_date menggunakan format ISO 8601, contoh: 2025-12-31T17:00:00Z. Opsional, bisa di-set ke null untuk menghapus deadline.
labels menerima array string bebas, contoh: ["work", "urgent"]. Opsional — default array kosong. Nilai di-trim dan di-dedupe otomatis. Saat update, mengirim labels akan mengganti seluruh daftar label (kirim [] untuk menghapus semua label).
Query params untuk GET /tasks:
?status=pending— filter berdasarkan status?priority=high— filter berdasarkan priority?label=work— filter task yang memiliki label tertentu?overdue=true— tampilkan task yang sudah melewati deadline dan belum selesai?sort=manual— urutkan berdasarkan urutan manual (lihat bagian Reorder Task), bukandue_date
Query params bisa dikombinasikan, contoh: ?status=pending&priority=high&label=work.
Secara default, list task diurutkan: task dengan due_date terdekat di atas, task tanpa due_date di bawah. Gunakan ?sort=manual untuk menampilkan task sesuai urutan yang diatur lewat endpoint reorder.
Setiap task punya field position (integer). Task baru otomatis ditaruh di posisi paling akhir.
# Urutkan ulang seluruh task: kirim array id sesuai urutan yang diinginkan
curl -X PATCH http://localhost:3000/tasks/reorder \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"order":[3,1,2]}'order wajib berisi persis seluruh id task milik user yang bersangkutan, masing-masing sekali — jika ada yang kurang, lebih, duplikat, atau bukan milik user, request ditolak dengan 400. Response berisi daftar task yang sudah terurut sesuai order.
# Buat task dengan deadline, priority, dan label
curl -X POST http://localhost:3000/tasks \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"title":"Belajar Docker","due_date":"2025-12-31T17:00:00Z","priority":"high","labels":["work","urgent"]}'
# List task yang sudah overdue
curl "http://localhost:3000/tasks?overdue=true" \
-H "Authorization: Bearer $TOKEN"
# List task dengan priority high
curl "http://localhost:3000/tasks?priority=high" \
-H "Authorization: Bearer $TOKEN"
# List task dengan label "work"
curl "http://localhost:3000/tasks?label=work" \
-H "Authorization: Bearer $TOKEN"
# Update status dan hapus deadline
curl -X PATCH http://localhost:3000/tasks/1 \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"status":"done","due_date":null}'API ini siap dijalankan di Render (free tier).
-
Buat PostgreSQL database di Render → salin Internal Database URL
-
Buat Web Service — hubungkan repo ini
-
Build command:
npm install -
Start command:
npm start -
Environment variables:
Key Value DATABASE_URLInternal Database URL dari langkah 1 JWT_SECRETString random panjang ( openssl rand -hex 32)JWT_EXPIRES_IN1dNODE_ENVproduction
Render mengisi
PORTsecara otomatis. -
-
Jalankan migrasi via Shell tab di Render:
npm run migrate
-
Verifikasi:
GET https://<your-service>.onrender.com/healthharus mengembalikan{"status":"ok"}
Koneksi database di production menggunakan SSL (
ssl: { rejectUnauthorized: false }), diaktifkan otomatis saatNODE_ENV=production— lihatsrc/config/db.js.
users
id SERIAL PRIMARY KEY
email TEXT UNIQUE NOT NULL
password_hash TEXT NOT NULL
role TEXT NOT NULL DEFAULT 'user'
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
tasks
id SERIAL PRIMARY KEY
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
title TEXT NOT NULL
description TEXT
status TEXT NOT NULL DEFAULT 'pending'
due_date TIMESTAMPTZ
priority TEXT NOT NULL DEFAULT 'medium'
labels TEXT[] NOT NULL DEFAULT '{}'
position INTEGER NOT NULL
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
INDEX idx_tasks_user_id ON tasks(user_id)
INDEX idx_tasks_labels ON tasks USING GIN (labels)
INDEX idx_tasks_user_position ON tasks(user_id, position)idris-taskapi/
├── migrations/
│ ├── 001_init.sql # DDL tabel users dan tasks
│ ├── 002_add_due_date.sql
│ ├── 003_add_priority.sql
│ ├── 004_add_labels.sql
│ ├── 005_add_position.sql
│ └── run.js # Script runner migrasi
├── src/
│ ├── config/
│ │ └── db.js # PostgreSQL connection pool
│ ├── controllers/
│ │ ├── authController.js
│ │ └── taskController.js
│ ├── middleware/
│ │ └── auth.js # JWT verification middleware
│ ├── models/
│ │ ├── userModel.js
│ │ └── taskModel.js
│ ├── routes/
│ │ ├── authRoutes.js
│ │ └── taskRoutes.js
│ └── index.js # Entry point
├── docker-compose.yml
├── .env.example
└── package.json
- Schema:
usersdantasksdihubungkan via foreign key denganON DELETE CASCADE— task user ikut terhapus jika akun dihapus. Index padatasks.user_idmenjaga performa query per-user. - Auth: password di-hash bcrypt sebelum disimpan; JWT menyimpan
id,email, danroleagar API tetap stateless. - Authorization: setiap query task di-scope ke
req.user.id, sehingga user hanya bisa melihat dan memodifikasi task miliknya sendiri.
Lihat ROADMAP.md untuk rencana pengembangan ke depan.