Add toggle status functionality for business types and update listing filter
This commit is contained in:
parent
104a58e6e7
commit
f1c3f28f95
47
AGENTS.md
Normal file
47
AGENTS.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Aturan Utama
|
||||||
|
|
||||||
|
### Dokumentasi Perubahan
|
||||||
|
|
||||||
|
**WAJIB** catat setiap perubahan yang dilakukan ke dalam folder `docs/history/` setelah selesai mengerjakan suatu fitur/bugfix/refactor.
|
||||||
|
|
||||||
|
#### Format Penulisan
|
||||||
|
|
||||||
|
Buat file markdown dengan nama format: `YYYY-MM-DD-singkatan-perubahan.md`
|
||||||
|
|
||||||
|
Contoh: `2026-07-24-sidebar-icon-mode.md`
|
||||||
|
|
||||||
|
#### Struktur Dokumen
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Judul Perubahan
|
||||||
|
|
||||||
|
**Tanggal:** YYYY-MM-DD
|
||||||
|
**Status:** Selesai
|
||||||
|
|
||||||
|
## Tujuan
|
||||||
|
Deskripsi singkat tujuan perubahan.
|
||||||
|
|
||||||
|
## Yang Dikerjakan
|
||||||
|
|
||||||
|
### 1. Judul Sub Perubahan
|
||||||
|
- Detail perubahan yang dilakukan
|
||||||
|
- Sebelum → Sesudah (jika ada perubahan value)
|
||||||
|
|
||||||
|
## File yang Diubah
|
||||||
|
|
||||||
|
| File | Aksi | Detail |
|
||||||
|
|------|------|--------|
|
||||||
|
| `path/to/file` | Diubah/Dibuat/Dihapus | Penjelasan singkat |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
Catatan tambahan jika perlu.
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Aturan Tambahan
|
||||||
|
|
||||||
|
- Selalu cantumkan file apa saja yang diubah, dibuat, atau dihapus
|
||||||
|
- Gunakan tabel untuk perubahan value (sebelum → sesudah)
|
||||||
|
- Cantumkan behavior/efek perubahan jika relevan
|
||||||
|
- Dokumen harus dalam Bahasa Indonesia
|
||||||
@ -6,6 +6,7 @@ from app.responses import created_response
|
|||||||
from app.schemas.business_type import (
|
from app.schemas.business_type import (
|
||||||
BusinessTypeCreate,
|
BusinessTypeCreate,
|
||||||
BusinessTypeResponse,
|
BusinessTypeResponse,
|
||||||
|
BusinessTypeToggleStatus,
|
||||||
BusinessTypeUpdate,
|
BusinessTypeUpdate,
|
||||||
)
|
)
|
||||||
from app.services.business_type_service import (
|
from app.services.business_type_service import (
|
||||||
@ -13,6 +14,7 @@ from app.services.business_type_service import (
|
|||||||
delete_business_type,
|
delete_business_type,
|
||||||
get_business_type_by_id,
|
get_business_type_by_id,
|
||||||
get_business_type_list,
|
get_business_type_list,
|
||||||
|
toggle_business_type_status,
|
||||||
update_business_type,
|
update_business_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,8 +22,8 @@ router = APIRouter(prefix="/business-types", tags=["business-types"])
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=list[BusinessTypeResponse])
|
@router.get("/", response_model=list[BusinessTypeResponse])
|
||||||
def list_business_types(db: Session = Depends(get_db)):
|
def list_business_types(is_active: bool = None, db: Session = Depends(get_db)):
|
||||||
return get_business_type_list(db)
|
return get_business_type_list(db, is_active=is_active)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{id}", response_model=BusinessTypeResponse)
|
@router.get("/{id}", response_model=BusinessTypeResponse)
|
||||||
@ -48,3 +50,10 @@ def update_business_type_route(
|
|||||||
@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT)
|
@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||||
def delete_business_type_route(id: str, db: Session = Depends(get_db)):
|
def delete_business_type_route(id: str, db: Session = Depends(get_db)):
|
||||||
delete_business_type(db, id)
|
delete_business_type(db, id)
|
||||||
|
|
||||||
|
|
||||||
|
@router.patch("/{id}/active", response_model=BusinessTypeResponse)
|
||||||
|
def toggle_business_type_status_route(
|
||||||
|
id: str, data: BusinessTypeToggleStatus, db: Session = Depends(get_db)
|
||||||
|
):
|
||||||
|
return toggle_business_type_status(db, id, data)
|
||||||
|
|||||||
@ -16,6 +16,10 @@ class BusinessTypeUpdate(BaseModel):
|
|||||||
is_active: bool | None = None
|
is_active: bool | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class BusinessTypeToggleStatus(BaseModel):
|
||||||
|
is_active: bool
|
||||||
|
|
||||||
|
|
||||||
class BusinessTypeResponse(BaseModel):
|
class BusinessTypeResponse(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
code: str
|
code: str
|
||||||
|
|||||||
@ -4,11 +4,14 @@ from fastapi import HTTPException, status
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.models.business_type import BusinessType
|
from app.models.business_type import BusinessType
|
||||||
from app.schemas.business_type import BusinessTypeCreate, BusinessTypeUpdate
|
from app.schemas.business_type import BusinessTypeCreate, BusinessTypeToggleStatus, BusinessTypeUpdate
|
||||||
|
|
||||||
|
|
||||||
def get_business_type_list(db: Session):
|
def get_business_type_list(db: Session, is_active: bool = None):
|
||||||
return db.query(BusinessType).filter(BusinessType.deleted_at.is_(None)).all()
|
query = db.query(BusinessType).filter(BusinessType.deleted_at.is_(None))
|
||||||
|
if is_active is not None:
|
||||||
|
query = query.filter(BusinessType.is_active == is_active)
|
||||||
|
return query.all()
|
||||||
|
|
||||||
|
|
||||||
def get_business_type_by_id(db: Session, id: str):
|
def get_business_type_by_id(db: Session, id: str):
|
||||||
@ -72,3 +75,17 @@ def delete_business_type(db: Session, id: str):
|
|||||||
|
|
||||||
bt.deleted_at = datetime.now()
|
bt.deleted_at = datetime.now()
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def toggle_business_type_status(db: Session, id: str, data: BusinessTypeToggleStatus):
|
||||||
|
bt = db.query(BusinessType).filter(BusinessType.id == id, BusinessType.deleted_at.is_(None)).first()
|
||||||
|
if not bt:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
detail={"message": "The item does not exist"},
|
||||||
|
)
|
||||||
|
|
||||||
|
bt.is_active = data.is_active
|
||||||
|
db.commit()
|
||||||
|
db.refresh(bt)
|
||||||
|
return bt
|
||||||
|
|||||||
33
docs/history/2026-07-24-toggle-status-business-type.md
Normal file
33
docs/history/2026-07-24-toggle-status-business-type.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Endpoint Toggle Status Business Type
|
||||||
|
|
||||||
|
**Tanggal:** 2026-07-24
|
||||||
|
**Status:** Selesai
|
||||||
|
|
||||||
|
## Tujuan
|
||||||
|
Menambahkan endpoint terpisah untuk toggle status (is_active) Business Type agar tidak bergabung dengan endpoint update umum.
|
||||||
|
|
||||||
|
## Yang Dikerjakan
|
||||||
|
|
||||||
|
### 1. Schema Toggle Status
|
||||||
|
- Menambahkan `BusinessTypeToggleStatus` dengan field `is_active: bool` (required)
|
||||||
|
|
||||||
|
### 2. Service Toggle Status
|
||||||
|
- Menambahkan `toggle_business_type_status()` — update field `is_active` saja pada entity
|
||||||
|
- Validasi entity exists dan tidak terhapus (soft delete)
|
||||||
|
|
||||||
|
### 3. Endpoint PATCH
|
||||||
|
- Menambahkan `PATCH /v1/business-types/{id}/active`
|
||||||
|
- Request body: `{ "is_active": true/false }`
|
||||||
|
- Response: `BusinessTypeResponse` (entity terbaru)
|
||||||
|
|
||||||
|
## File yang Diubah
|
||||||
|
|
||||||
|
| File | Aksi | Detail |
|
||||||
|
|------|------|--------|
|
||||||
|
| `api/app/schemas/business_type.py` | Diubah | Tambah `BusinessTypeToggleStatus` schema |
|
||||||
|
| `api/app/services/business_type_service.py` | Diubah | Tambah `toggle_business_type_status()` function |
|
||||||
|
| `api/app/routers/business_types.py` | Diubah | Tambah import + `PATCH /{id}/active` endpoint |
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- Endpoint PATCH terpisah dari PUT agar frontend bisa toggle status tanpa mengirim field lain
|
||||||
|
- Frontend menggunakan optimistic update setelah PATCH berhasil
|
||||||
Loading…
Reference in New Issue
Block a user