Remove 'code' field from BusinessType model, schemas, factory, and service; update related tests
This commit is contained in:
parent
f1c3f28f95
commit
5772a3948d
@ -8,7 +8,6 @@ class BusinessTypeFactory(Factory):
|
||||
def definition(self) -> dict:
|
||||
return {
|
||||
"id": None,
|
||||
"code": random_string(8),
|
||||
"name": f"Business {random_string(6).title()}",
|
||||
"description": None,
|
||||
"is_active": True,
|
||||
|
||||
@ -12,7 +12,6 @@ class BusinessType(Base):
|
||||
__tablename__ = "business_types"
|
||||
|
||||
id: Mapped[str] = mapped_column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
||||
code: Mapped[str] = mapped_column(String(30), unique=True)
|
||||
name: Mapped[str] = mapped_column(String(100))
|
||||
description: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
|
||||
@ -4,13 +4,11 @@ from pydantic import BaseModel
|
||||
|
||||
|
||||
class BusinessTypeCreate(BaseModel):
|
||||
code: str
|
||||
name: str
|
||||
description: str | None = None
|
||||
|
||||
|
||||
class BusinessTypeUpdate(BaseModel):
|
||||
code: str | None = None
|
||||
name: str | None = None
|
||||
description: str | None = None
|
||||
is_active: bool | None = None
|
||||
@ -22,7 +20,6 @@ class BusinessTypeToggleStatus(BaseModel):
|
||||
|
||||
class BusinessTypeResponse(BaseModel):
|
||||
id: str
|
||||
code: str
|
||||
name: str
|
||||
description: str | None
|
||||
is_active: bool
|
||||
|
||||
@ -11,7 +11,7 @@ def get_business_type_list(db: Session, is_active: bool = None):
|
||||
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()
|
||||
return query.order_by(BusinessType.created_at.desc()).all()
|
||||
|
||||
|
||||
def get_business_type_by_id(db: Session, id: str):
|
||||
@ -25,13 +25,6 @@ def get_business_type_by_id(db: Session, id: str):
|
||||
|
||||
|
||||
def create_business_type(db: Session, data: BusinessTypeCreate):
|
||||
existing = db.query(BusinessType).filter(BusinessType.code == data.code).first()
|
||||
if existing:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail={"message": "Code already exists"},
|
||||
)
|
||||
|
||||
bt = BusinessType(**data.model_dump())
|
||||
db.add(bt)
|
||||
db.commit()
|
||||
@ -49,14 +42,6 @@ def update_business_type(db: Session, id: str, data: BusinessTypeUpdate):
|
||||
|
||||
update_data = data.model_dump(exclude_unset=True)
|
||||
|
||||
if "code" in update_data:
|
||||
dup = db.query(BusinessType).filter(BusinessType.code == update_data["code"], BusinessType.id != id).first()
|
||||
if dup:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail={"message": "Code already exists"},
|
||||
)
|
||||
|
||||
for field, value in update_data.items():
|
||||
setattr(bt, field, value)
|
||||
|
||||
|
||||
44
docs/history/2026-07-24-hapus-kode-business-type.md
Normal file
44
docs/history/2026-07-24-hapus-kode-business-type.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Hapus Kolom Code dari Business Type
|
||||
|
||||
**Tanggal:** 2026-07-24
|
||||
**Status:** Selesai
|
||||
|
||||
## Tujuan
|
||||
Menghapus kolom `code` dari tabel `business_types` dan seluruh referensinya di API.
|
||||
|
||||
## Yang Dikerjakan
|
||||
|
||||
### 1. Model
|
||||
- Hapus field `code: Mapped[str]` dari `BusinessType` model
|
||||
- Sebelum: `code`, `name`, `description`, `is_active`
|
||||
- Sesudah: `name`, `description`, `is_active`
|
||||
|
||||
### 2. Schema
|
||||
- Hapus `code` dari `BusinessTypeCreate`, `BusinessTypeUpdate`, `BusinessTypeResponse`
|
||||
- Sebelum: `BusinessTypeCreate(code, name, description)`
|
||||
- Sesudah: `BusinessTypeCreate(name, description)`
|
||||
|
||||
### 3. Service
|
||||
- Hapus uniqueness check `code` di `create_business_type()`
|
||||
- Hapus uniqueness check `code` di `update_business_type()`
|
||||
|
||||
### 4. Factory
|
||||
- Hapus `code` dari `BusinessTypeFactory.definition()`
|
||||
|
||||
### 5. Tests
|
||||
- Hapus semua referensi `code` dari test service dan API
|
||||
- Hapus test `test_create_duplicate_code` dan `test_update_conflict_code`
|
||||
|
||||
## File yang Diubah
|
||||
|
||||
| File | Aksi | Detail |
|
||||
|------|------|--------|
|
||||
| `api/app/models/business_type.py` | Diubah | Hapus field `code` |
|
||||
| `api/app/schemas/business_type.py` | Diubah | Hapus `code` dari Create, Update, Response |
|
||||
| `api/app/services/business_type_service.py` | Diubah | Hapus uniqueness check `code` |
|
||||
| `api/app/factories/business_type_factory.py` | Diubah | Hapus `code` dari definition |
|
||||
| `api/tests/test_business_type.py` | Diubah | Hapus referensi `code` dan test duplikasi |
|
||||
|
||||
## Notes
|
||||
- Perlu jalankan SQL `ALTER TABLE business_types DROP COLUMN code;` di database
|
||||
- Tidak ada migrasi tool (Alembic), jadi harus manual via SQL
|
||||
@ -19,19 +19,12 @@ class TestService:
|
||||
assert get_business_type_list(db_session) == []
|
||||
|
||||
def test_create(self, db_session: Session):
|
||||
data = BusinessTypeCreate(code="RETAIL", name="Retail")
|
||||
data = BusinessTypeCreate(name="Retail")
|
||||
bt = create_business_type(db_session, data)
|
||||
assert bt.code == "RETAIL"
|
||||
assert bt.name == "Retail"
|
||||
|
||||
def test_create_duplicate_code(self, db_session: Session):
|
||||
create_business_type(db_session, BusinessTypeCreate(code="RETAIL", name="A"))
|
||||
with pytest.raises(HTTPException) as exc:
|
||||
create_business_type(db_session, BusinessTypeCreate(code="RETAIL", name="B"))
|
||||
assert exc.value.status_code == 409
|
||||
|
||||
def test_get_by_id(self, db_session: Session):
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(code="GROCERY", name="Grocery"))
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(name="Grocery"))
|
||||
result = get_business_type_by_id(db_session, bt.id)
|
||||
assert result.id == bt.id
|
||||
|
||||
@ -41,25 +34,18 @@ class TestService:
|
||||
assert exc.value.status_code == 404
|
||||
|
||||
def test_update(self, db_session: Session):
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(code="CAFE", name="Cafe"))
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(name="Cafe"))
|
||||
data = BusinessTypeUpdate(name="Coffee Shop")
|
||||
updated = update_business_type(db_session, bt.id, data)
|
||||
assert updated.name == "Coffee Shop"
|
||||
|
||||
def test_update_conflict_code(self, db_session: Session):
|
||||
create_business_type(db_session, BusinessTypeCreate(code="A", name="A"))
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(code="B", name="B"))
|
||||
with pytest.raises(HTTPException) as exc:
|
||||
update_business_type(db_session, bt.id, BusinessTypeUpdate(code="A"))
|
||||
assert exc.value.status_code == 409
|
||||
|
||||
def test_update_not_found(self, db_session: Session):
|
||||
with pytest.raises(HTTPException) as exc:
|
||||
update_business_type(db_session, "x", BusinessTypeUpdate(name="X"))
|
||||
assert exc.value.status_code == 404
|
||||
|
||||
def test_delete(self, db_session: Session):
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(code="DEL", name="Del"))
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(name="Del"))
|
||||
delete_business_type(db_session, bt.id)
|
||||
assert bt.deleted_at is not None
|
||||
|
||||
@ -69,32 +55,32 @@ class TestService:
|
||||
assert exc.value.status_code == 404
|
||||
|
||||
def test_soft_deleted_excluded(self, db_session: Session):
|
||||
create_business_type(db_session, BusinessTypeCreate(code="KEEP", name="Keep"))
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(code="GONE", name="Gone"))
|
||||
create_business_type(db_session, BusinessTypeCreate(name="Keep"))
|
||||
bt = create_business_type(db_session, BusinessTypeCreate(name="Gone"))
|
||||
delete_business_type(db_session, bt.id)
|
||||
assert len(get_business_type_list(db_session)) == 1
|
||||
|
||||
|
||||
class TestAPI:
|
||||
def test_create(self, client: TestClient):
|
||||
resp = client.post("/v1/business-types/", json={"code": "TOKO", "name": "Toko"})
|
||||
resp = client.post("/v1/business-types/", json={"name": "Toko"})
|
||||
assert resp.status_code == 201
|
||||
assert resp.json() == {"message": "The item was created successfully"}
|
||||
|
||||
def test_list(self, client: TestClient, db_session: Session):
|
||||
db_session.add(BusinessType(code="A", name="A"))
|
||||
db_session.add(BusinessType(name="A"))
|
||||
db_session.commit()
|
||||
resp = client.get("/v1/business-types/")
|
||||
assert resp.status_code == 200
|
||||
assert len(resp.json()) == 1
|
||||
|
||||
def test_get_by_id(self, client: TestClient, db_session: Session):
|
||||
bt = BusinessType(code="GET", name="Get")
|
||||
bt = BusinessType(name="Get")
|
||||
db_session.add(bt)
|
||||
db_session.commit()
|
||||
resp = client.get(f"/v1/business-types/{bt.id}")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["code"] == "GET"
|
||||
assert resp.json()["name"] == "Get"
|
||||
|
||||
def test_get_not_found(self, client: TestClient):
|
||||
resp = client.get("/v1/business-types/x")
|
||||
@ -102,7 +88,7 @@ class TestAPI:
|
||||
assert resp.json() == {"message": "The item does not exist"}
|
||||
|
||||
def test_update(self, client: TestClient, db_session: Session):
|
||||
bt = BusinessType(code="UPD", name="Old")
|
||||
bt = BusinessType(name="Old")
|
||||
db_session.add(bt)
|
||||
db_session.commit()
|
||||
resp = client.put(f"/v1/business-types/{bt.id}", json={"name": "New"})
|
||||
@ -110,7 +96,7 @@ class TestAPI:
|
||||
assert resp.json()["name"] == "New"
|
||||
|
||||
def test_delete(self, client: TestClient, db_session: Session):
|
||||
bt = BusinessType(code="DEL", name="Del")
|
||||
bt = BusinessType(name="Del")
|
||||
db_session.add(bt)
|
||||
db_session.commit()
|
||||
resp = client.delete(f"/v1/business-types/{bt.id}")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user