Compare commits
No commits in common. "169269267db94c73d62c4bae2db040bc724d6519" and "ab112c1c5b372df9876cbe89e8a245986b082f64" have entirely different histories.
169269267d
...
ab112c1c5b
29
.gitignore
vendored
29
.gitignore
vendored
@ -1,29 +0,0 @@
|
|||||||
# Python
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
*$py.class
|
|
||||||
.pytest_cache/
|
|
||||||
.mypy_cache/
|
|
||||||
.ruff_cache/
|
|
||||||
.coverage
|
|
||||||
htmlcov/
|
|
||||||
|
|
||||||
# Virtual environment
|
|
||||||
.venv/
|
|
||||||
venv/
|
|
||||||
env/
|
|
||||||
|
|
||||||
# Environment/config secrets
|
|
||||||
.env
|
|
||||||
.env.*
|
|
||||||
!.env.example
|
|
||||||
|
|
||||||
# Local databases
|
|
||||||
*.db
|
|
||||||
*.sqlite
|
|
||||||
*.sqlite3
|
|
||||||
|
|
||||||
# IDE / OS
|
|
||||||
.idea/
|
|
||||||
.vscode/
|
|
||||||
.DS_Store
|
|
||||||
512
README.md
512
README.md
@ -1,512 +0,0 @@
|
|||||||
# API Playground
|
|
||||||
|
|
||||||
Proyek sederhana untuk playground API enrollment berbasis Python Bottle dan SQLite.
|
|
||||||
|
|
||||||
Aplikasi ini menyediakan halaman UI playground dan API endpoint untuk mengelola data enrollment secara CRUD.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Fitur
|
|
||||||
|
|
||||||
- Server API berbasis Bottle
|
|
||||||
- Database SQLite
|
|
||||||
- UI playground untuk testing endpoint langsung dari browser
|
|
||||||
- Autentikasi sederhana menggunakan Bearer Token
|
|
||||||
- Validasi nilai `type` dan `service`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Requirements
|
|
||||||
|
|
||||||
Pastikan sudah terinstall:
|
|
||||||
|
|
||||||
- Python 3
|
|
||||||
- pip
|
|
||||||
- Git
|
|
||||||
|
|
||||||
> Catatan: Di Windows, umumnya gunakan `py` untuk menjalankan Python dan `py -m pip` untuk menjalankan pip, karena Python installer resmi Windows biasanya mendaftarkan Python melalui Python Launcher (`py`).
|
|
||||||
|
|
||||||
### Untuk Pengguna Windows
|
|
||||||
|
|
||||||
Sebelum menjalankan project, install tools berikut:
|
|
||||||
|
|
||||||
1. **Python 3**
|
|
||||||
- Download installer Python terbaru dari: https://www.python.org/downloads/windows/
|
|
||||||
- Saat instalasi, centang opsi **Add python.exe to PATH**
|
|
||||||
- Pastikan `pip` ikut terinstall bersama Python
|
|
||||||
|
|
||||||
2. **Git for Windows**
|
|
||||||
- Download dari: https://git-scm.com/download/win
|
|
||||||
- Gunakan opsi default saat instalasi
|
|
||||||
|
|
||||||
3. **Terminal**
|
|
||||||
- Bisa menggunakan **Command Prompt**, **PowerShell**, atau **Windows Terminal**
|
|
||||||
|
|
||||||
4. **Text Editor / IDE** *(opsional)*
|
|
||||||
- Visual Studio Code, PyCharm, atau editor lain sesuai preferensi
|
|
||||||
|
|
||||||
> Catatan: SQLite sudah tersedia sebagai library bawaan Python, jadi tidak perlu install SQLite secara terpisah.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ Instalasi
|
|
||||||
|
|
||||||
### 1. Clone / Masuk ke Folder Project
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd api-playground
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Buat Virtual Environment
|
|
||||||
|
|
||||||
Disarankan menggunakan virtual environment agar dependency tidak bercampur dengan environment global.
|
|
||||||
|
|
||||||
Di Linux/macOS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python3 -m venv venv
|
|
||||||
```
|
|
||||||
|
|
||||||
Di Windows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
py -m venv venv
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Aktifkan Virtual Environment
|
|
||||||
|
|
||||||
Di Linux/macOS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
source venv/bin/activate
|
|
||||||
```
|
|
||||||
|
|
||||||
Di Windows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
venv\Scripts\activate
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Install Dependencies
|
|
||||||
|
|
||||||
Di Linux/macOS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
Di Windows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
py -m pip install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ▶️ Menjalankan Aplikasi
|
|
||||||
|
|
||||||
Jalankan server dengan perintah:
|
|
||||||
|
|
||||||
Di Linux/macOS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python app.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Di Windows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
py app.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Server akan berjalan di:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
http://localhost:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
atau:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
http://0.0.0.0:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
Jika port `8080` sudah terpakai, gunakan opsi `--port` untuk mengganti port server.
|
|
||||||
|
|
||||||
Di Linux/macOS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python app.py --port 5000
|
|
||||||
```
|
|
||||||
|
|
||||||
Di Windows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
py app.py --port 5000
|
|
||||||
```
|
|
||||||
|
|
||||||
Server kemudian dapat diakses di:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
http://localhost:5000
|
|
||||||
```
|
|
||||||
|
|
||||||
Untuk mengganti host dan port sekaligus:
|
|
||||||
|
|
||||||
Di Linux/macOS:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python app.py --host 127.0.0.1 --port 5000
|
|
||||||
```
|
|
||||||
|
|
||||||
Di Windows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
py app.py --host 127.0.0.1 --port 5000
|
|
||||||
```
|
|
||||||
|
|
||||||
Jika kode diubah, server akan otomatis restart karena menggunakan mode `debug=True` dan `reloader=True`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔐 Autentikasi
|
|
||||||
|
|
||||||
Semua request ke endpoint API wajib menyertakan header:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
Authorization: Bearer secret123
|
|
||||||
```
|
|
||||||
|
|
||||||
Token default disimpan di `app.py` pada variabel:
|
|
||||||
|
|
||||||
```python
|
|
||||||
API_TOKEN = "secret123"
|
|
||||||
```
|
|
||||||
|
|
||||||
Jika tidak menyertakan token atau token salah, API akan mengembalikan response `401 Unauthorized`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📡 Daftar Endpoint
|
|
||||||
|
|
||||||
| Endpoint | Method | Auth | Fungsi |
|
|
||||||
|---|---|---|---|
|
|
||||||
| `/` | `GET` | Tidak | Halaman playground UI |
|
|
||||||
| `/api/enroll` | `GET` | Ya | List semua enrollment |
|
|
||||||
| `/api/enroll?id=<id>` | `GET` | Ya | Mendapatkan detail enrollment berdasarkan ID |
|
|
||||||
| `/api/enroll` | `POST` | Ya | Tambah, edit, atau hapus enrollment |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧬 Database Schema
|
|
||||||
|
|
||||||
Tabel: `enroll`
|
|
||||||
|
|
||||||
| Kolom | Tipe | Keterangan |
|
|
||||||
|---|---|---|
|
|
||||||
| `id` | INTEGER | Primary key, auto-increment |
|
|
||||||
| `type` | TEXT | Tipe enrollment, hanya boleh `Annually` atau `Monthly` |
|
|
||||||
| `service` | TEXT | Paket layanan, hanya boleh `Lite`, `Value`, atau `Pro` |
|
|
||||||
| `user` | TEXT | Nama pengguna |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 Penggunaan Endpoint
|
|
||||||
|
|
||||||
### 1. List Semua Enrollment
|
|
||||||
|
|
||||||
**Request**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -H "Authorization: Bearer secret123" \
|
|
||||||
http://localhost:8080/api/enroll
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"id": 2,
|
|
||||||
"type": "Monthly",
|
|
||||||
"service": "Lite",
|
|
||||||
"user": "bob"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"type": "Annually",
|
|
||||||
"service": "Pro",
|
|
||||||
"user": "alice"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. Detail Enrollment Berdasarkan ID
|
|
||||||
|
|
||||||
**Request**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -H "Authorization: Bearer secret123" \
|
|
||||||
"http://localhost:8080/api/enroll?id=1"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"id": 1,
|
|
||||||
"type": "Annually",
|
|
||||||
"service": "Pro",
|
|
||||||
"user": "alice"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Jika ID tidak ditemukan:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"error": "not found"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. Tambah Enrollment Baru
|
|
||||||
|
|
||||||
Endpoint `POST /api/enroll` dapat menerima data dalam format form-urlencoded atau JSON.
|
|
||||||
|
|
||||||
#### Menggunakan Form Data
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/api/enroll \
|
|
||||||
-H "Authorization: Bearer secret123" \
|
|
||||||
-d "type=Annually" \
|
|
||||||
-d "service=Pro" \
|
|
||||||
-d "user=alice"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Menggunakan JSON
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/api/enroll \
|
|
||||||
-H "Authorization: Bearer secret123" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"type": "Annually",
|
|
||||||
"service": "Pro",
|
|
||||||
"user": "alice"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "created",
|
|
||||||
"id": 1
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. Edit Enrollment
|
|
||||||
|
|
||||||
Untuk melakukan edit, kirim field `id` bersama data baru.
|
|
||||||
|
|
||||||
#### Menggunakan Form Data
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/api/enroll \
|
|
||||||
-H "Authorization: Bearer secret123" \
|
|
||||||
-d "id=1" \
|
|
||||||
-d "type=Monthly" \
|
|
||||||
-d "service=Value" \
|
|
||||||
-d "user=bob"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Menggunakan JSON
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/api/enroll \
|
|
||||||
-H "Authorization: Bearer secret123" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"id": 1,
|
|
||||||
"type": "Monthly",
|
|
||||||
"service": "Value",
|
|
||||||
"user": "bob"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "updated",
|
|
||||||
"id": 1
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. Hapus Enrollment
|
|
||||||
|
|
||||||
Untuk menghapus data, gunakan `POST /api/enroll` dengan field:
|
|
||||||
|
|
||||||
- `id`
|
|
||||||
- `action=remove`
|
|
||||||
|
|
||||||
#### Menggunakan Form Data
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/api/enroll \
|
|
||||||
-H "Authorization: Bearer secret123" \
|
|
||||||
-d "id=1" \
|
|
||||||
-d "action=remove"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Menggunakan JSON
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST http://localhost:8080/api/enroll \
|
|
||||||
-H "Authorization: Bearer secret123" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"id": 1,
|
|
||||||
"action": "remove"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message": "removed",
|
|
||||||
"id": 1
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧠 Logika `POST /api/enroll`
|
|
||||||
|
|
||||||
```text
|
|
||||||
POST /api/enroll
|
|
||||||
│
|
|
||||||
├── action = "remove" → hapus data, wajib menyertakan id
|
|
||||||
├── ada field id → edit data
|
|
||||||
└── tidak ada field id → tambah data baru
|
|
||||||
```
|
|
||||||
|
|
||||||
Untuk tambah dan edit, field berikut wajib dikirim:
|
|
||||||
|
|
||||||
| Field | Wajib | Keterangan |
|
|
||||||
|---|---|---|
|
|
||||||
| `type` | Ya | Harus `Annually` atau `Monthly` |
|
|
||||||
| `service` | Ya | Harus `Lite`, `Value`, atau `Pro` |
|
|
||||||
| `user` | Ya | Nama pengguna |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ Validasi
|
|
||||||
|
|
||||||
Nilai yang diterima API:
|
|
||||||
|
|
||||||
```text
|
|
||||||
type:
|
|
||||||
- Annually
|
|
||||||
- Monthly
|
|
||||||
|
|
||||||
service:
|
|
||||||
- Lite
|
|
||||||
- Value
|
|
||||||
- Pro
|
|
||||||
```
|
|
||||||
|
|
||||||
Jika nilai tidak sesuai, API akan mengembalikan error `400 Bad Request`.
|
|
||||||
|
|
||||||
Contoh error:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"error": "type must be one of: Annually, Monthly"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"error": "service must be one of: Lite, Value, Pro"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎮 Menggunakan Playground UI
|
|
||||||
|
|
||||||
Setelah server berjalan, buka browser ke:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
http://localhost:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
Halaman playground dapat digunakan untuk:
|
|
||||||
|
|
||||||
1. Mengisi token Bearer
|
|
||||||
2. Melihat status autentikasi
|
|
||||||
3. Mengisi form request
|
|
||||||
4. Mengirim request ke endpoint
|
|
||||||
5. Melihat response JSON secara langsung
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧾 Contoh Response Error
|
|
||||||
|
|
||||||
| Status | Kondisi | Response |
|
|
||||||
|---|---|---|
|
|
||||||
| `401` | Tidak menyertakan Authorization header | `{"error": "missing or invalid Authorization header"}` |
|
|
||||||
| `401` | Token tidak valid | `{"error": "invalid token"}` |
|
|
||||||
| `400` | Field wajib kosong | `{"error": "type, service, user are required"}` |
|
|
||||||
| `400` | `type` tidak valid | `{"error": "type must be one of: Annually, Monthly"}` |
|
|
||||||
| `400` | `service` tidak valid | `{"error": "service must be one of: Lite, Value, Pro"}` |
|
|
||||||
| `400` | `id` bukan integer | `{"error": "id must be an integer"}` |
|
|
||||||
| `404` | Data tidak ditemukan | `{"error": "not found"}` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Struktur Project
|
|
||||||
|
|
||||||
```text
|
|
||||||
api-playground/
|
|
||||||
├── app.py # Routing API dan konfigurasi aplikasi
|
|
||||||
├── db.py # Koneksi dan operasi database SQLite
|
|
||||||
├── enroll.db # Database SQLite
|
|
||||||
├── requirements.txt # Dependency Python
|
|
||||||
├── templates/
|
|
||||||
│ └── playground.html # UI playground
|
|
||||||
└── README.md # Dokumentasi project
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Catatan
|
|
||||||
|
|
||||||
- Token default hanya untuk development. Untuk production, gunakan token yang lebih aman dan simpan melalui environment variable.
|
|
||||||
- Database SQLite disimpan dalam file `enroll.db`.
|
|
||||||
- Mode debug dan reloader aktif saat menjalankan `python app.py` / `py app.py`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🤝 Kontribusi
|
|
||||||
|
|
||||||
Untuk menambahkan fitur baru:
|
|
||||||
|
|
||||||
1. Buat perubahan pada kode
|
|
||||||
2. Jalankan server untuk memastikan tidak ada error
|
|
||||||
3. Tes endpoint menggunakan playground UI atau `curl`
|
|
||||||
4. Dokumentasikan perubahan jika endpoint atau behavior berubah
|
|
||||||
39
app.py
39
app.py
@ -18,18 +18,6 @@ def json_response(data, status=200):
|
|||||||
return json.dumps(data)
|
return json.dumps(data)
|
||||||
|
|
||||||
|
|
||||||
def get_request_params():
|
|
||||||
"""
|
|
||||||
Ambil parameter request dari form URL-encoded atau JSON.
|
|
||||||
Ini menjaga endpoint tetap kompatibel dengan curl, playground, dan tools API.
|
|
||||||
"""
|
|
||||||
if request.content_type.startswith("application/json"):
|
|
||||||
payload = request.json or {}
|
|
||||||
return {key: str(value) for key, value in payload.items()}
|
|
||||||
|
|
||||||
return request.forms
|
|
||||||
|
|
||||||
|
|
||||||
def check_auth():
|
def check_auth():
|
||||||
"""
|
"""
|
||||||
Cek Bearer token.
|
Cek Bearer token.
|
||||||
@ -85,28 +73,19 @@ def api_enroll_post():
|
|||||||
if err:
|
if err:
|
||||||
return json_response(json.loads(err), 401)
|
return json_response(json.loads(err), 401)
|
||||||
|
|
||||||
params = get_request_params()
|
action = request.forms.get("action", "").strip()
|
||||||
action = params.get("action", "").strip()
|
enroll_id = request.forms.get("id", "").strip()
|
||||||
enroll_id = params.get("id", "").strip()
|
type_ = request.forms.get("type", "").strip()
|
||||||
type_ = params.get("type", "").strip()
|
service = request.forms.get("service", "").strip()
|
||||||
service = params.get("service", "").strip()
|
user = request.forms.get("user", "").strip()
|
||||||
user = params.get("user", "").strip()
|
|
||||||
|
|
||||||
# ── remove ──
|
# ── remove ──
|
||||||
if action == "remove":
|
if action == "remove":
|
||||||
if not enroll_id:
|
if not enroll_id:
|
||||||
return json_response({"error": "id is required for remove"}, 400)
|
return json_response({"error": "id is required for remove"}, 400)
|
||||||
if not enroll_id.isdigit():
|
|
||||||
return json_response({"error": "id must be an integer"}, 400)
|
|
||||||
if not db.get_enroll(int(enroll_id)):
|
|
||||||
return json_response({"error": "not found"}, 404)
|
|
||||||
db.remove_enroll(int(enroll_id))
|
db.remove_enroll(int(enroll_id))
|
||||||
return json_response({"message": "removed", "id": int(enroll_id)})
|
return json_response({"message": "removed", "id": int(enroll_id)})
|
||||||
|
|
||||||
# ── validate required fields ──
|
|
||||||
if not type_ or not service or not user:
|
|
||||||
return json_response({"error": "type, service, user are required"}, 400)
|
|
||||||
|
|
||||||
# ── validate type ──
|
# ── validate type ──
|
||||||
if type_ not in db.VALID_TYPES:
|
if type_ not in db.VALID_TYPES:
|
||||||
return json_response(
|
return json_response(
|
||||||
@ -121,14 +100,14 @@ def api_enroll_post():
|
|||||||
|
|
||||||
# ── edit ──
|
# ── edit ──
|
||||||
if enroll_id:
|
if enroll_id:
|
||||||
if not enroll_id.isdigit():
|
if not type_ or not service or not user:
|
||||||
return json_response({"error": "id must be an integer"}, 400)
|
return json_response({"error": "type, service, user are required"}, 400)
|
||||||
if not db.get_enroll(int(enroll_id)):
|
|
||||||
return json_response({"error": "not found"}, 404)
|
|
||||||
db.edit_enroll(int(enroll_id), type_, service, user)
|
db.edit_enroll(int(enroll_id), type_, service, user)
|
||||||
return json_response({"message": "updated", "id": int(enroll_id)})
|
return json_response({"message": "updated", "id": int(enroll_id)})
|
||||||
|
|
||||||
# ── add ──
|
# ── add ──
|
||||||
|
if not type_ or not service or not user:
|
||||||
|
return json_response({"error": "type, service, user are required"}, 400)
|
||||||
new_id = db.add_enroll(type_, service, user)
|
new_id = db.add_enroll(type_, service, user)
|
||||||
return json_response({"message": "created", "id": new_id}, 201)
|
return json_response({"message": "created", "id": new_id}, 201)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user