数据:增加测试批次模型与迁移契约
This commit is contained in:
@@ -28,3 +28,14 @@ class PalletEventType(str, Enum):
|
||||
USAGE_RECORDED = 'USAGE_RECORDED'
|
||||
RETURN_REQUESTED = 'RETURN_REQUESTED'
|
||||
RETURN_CONFIRMED = 'RETURN_CONFIRMED'
|
||||
|
||||
|
||||
class TestBatchStatus(str, Enum):
|
||||
ACTIVE = 'ACTIVE'
|
||||
CLOSED = 'CLOSED'
|
||||
PURGED = 'PURGED'
|
||||
|
||||
|
||||
class TestBatchPreviewAction(str, Enum):
|
||||
ADOPT = 'ADOPT'
|
||||
PURGE = 'PURGE'
|
||||
|
||||
@@ -27,6 +27,13 @@ class BizStrain(Base):
|
||||
)
|
||||
|
||||
strain_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='菌种ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
strain_code = Column(String(64), nullable=False, unique=True, comment='菌种编码')
|
||||
strain_name = Column(String(100), nullable=False, comment='菌种名称')
|
||||
status = Column(CHAR(1), nullable=False, server_default='0', comment='状态(0正常 1停用)')
|
||||
@@ -52,6 +59,13 @@ class BizWarehouse(Base):
|
||||
)
|
||||
|
||||
warehouse_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='仓库ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
warehouse_code = Column(String(64), nullable=False, unique=True, comment='仓库编码')
|
||||
warehouse_name = Column(String(100), nullable=False, comment='仓库名称')
|
||||
address = Column(String(500), nullable=True, comment='仓库地址')
|
||||
@@ -78,6 +92,13 @@ class BizCustomer(Base):
|
||||
)
|
||||
|
||||
customer_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='客户ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
customer_code = Column(String(64), nullable=False, unique=True, comment='客户编码')
|
||||
customer_name = Column(String(100), nullable=False, comment='客户名称')
|
||||
status = Column(CHAR(1), nullable=False, server_default='0', comment='状态(0正常 1停用)')
|
||||
@@ -104,6 +125,13 @@ class BizCustomerSite(Base):
|
||||
)
|
||||
|
||||
site_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='现场ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
customer_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_customer.customer_id'),
|
||||
@@ -137,6 +165,13 @@ class BizProductionLine(Base):
|
||||
)
|
||||
|
||||
line_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='产线ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
site_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_customer_site.site_id'),
|
||||
@@ -169,6 +204,13 @@ class BizPallet(Base):
|
||||
)
|
||||
|
||||
pallet_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='托盘ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
pallet_code = Column(String(64), nullable=False, unique=True, comment='托盘编号')
|
||||
qr_token = Column(String(128), nullable=False, unique=True, comment='二维码固定标识')
|
||||
capacity_packages = Column(Integer, nullable=False, comment='容量包数')
|
||||
|
||||
@@ -22,6 +22,13 @@ class BizInboundOrder(Base):
|
||||
)
|
||||
|
||||
inbound_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='入库单ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
inbound_no = Column(String(64), nullable=False, unique=True, comment='入库单号')
|
||||
warehouse_id = Column(
|
||||
BigInteger,
|
||||
@@ -62,6 +69,13 @@ class BizInboundItem(Base):
|
||||
autoincrement=True,
|
||||
comment='入库明细ID',
|
||||
)
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
inbound_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_inbound_order.inbound_id'),
|
||||
@@ -93,6 +107,13 @@ class BizFillingRecord(Base):
|
||||
)
|
||||
|
||||
filling_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='装填记录ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
filling_no = Column(String(64), nullable=False, unique=True, comment='装填单号')
|
||||
pallet_id = Column(BigInteger, ForeignKey('biz_pallet.pallet_id'), nullable=False, comment='托盘ID')
|
||||
warehouse_id = Column(
|
||||
@@ -141,6 +162,13 @@ class BizShipmentOrder(Base):
|
||||
)
|
||||
|
||||
shipment_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='发货单ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
shipment_no = Column(String(64), nullable=False, unique=True, comment='发货单号')
|
||||
source_warehouse_id = Column(
|
||||
BigInteger,
|
||||
@@ -191,6 +219,13 @@ class BizShipmentItem(Base):
|
||||
autoincrement=True,
|
||||
comment='发货明细ID',
|
||||
)
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
shipment_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_shipment_order.shipment_id'),
|
||||
@@ -224,6 +259,13 @@ class BizUsageRecord(Base):
|
||||
)
|
||||
|
||||
usage_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='使用记录ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
usage_no = Column(String(64), nullable=False, unique=True, comment='使用记录号')
|
||||
pallet_id = Column(BigInteger, ForeignKey('biz_pallet.pallet_id'), nullable=False, comment='托盘ID')
|
||||
active_filling_id = Column(
|
||||
@@ -264,6 +306,13 @@ class BizReturnOrder(Base):
|
||||
)
|
||||
|
||||
return_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='退回单ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
return_no = Column(String(64), nullable=False, unique=True, comment='退回单号')
|
||||
source_site_id = Column(
|
||||
BigInteger,
|
||||
@@ -318,6 +367,13 @@ class BizReturnItem(Base):
|
||||
autoincrement=True,
|
||||
comment='退回明细ID',
|
||||
)
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
return_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_return_order.return_id'),
|
||||
@@ -363,6 +419,13 @@ class BizPalletInventory(Base):
|
||||
autoincrement=False,
|
||||
comment='托盘ID',
|
||||
)
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
active_filling_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_filling_record.filling_id'),
|
||||
@@ -415,6 +478,13 @@ class BizPalletEvent(Base):
|
||||
)
|
||||
|
||||
event_id = Column(BigInteger, primary_key=True, nullable=False, autoincrement=True, comment='事件ID')
|
||||
test_batch_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey('biz_test_batch.batch_id'),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment='测试数据批次ID;NULL表示正式数据',
|
||||
)
|
||||
pallet_id = Column(BigInteger, ForeignKey('biz_pallet.pallet_id'), nullable=False, comment='托盘ID')
|
||||
event_seq = Column(Integer, nullable=False, comment='托盘内事件序号')
|
||||
event_type = Column(String(32), nullable=False, comment='事件类型')
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import CHAR, BigInteger, CheckConstraint, Column, DateTime, ForeignKey, String, Text
|
||||
|
||||
from config.database import Base
|
||||
|
||||
|
||||
class BizTestBatch(Base):
|
||||
"""测试数据批次。"""
|
||||
|
||||
__tablename__ = 'biz_test_batch'
|
||||
__table_args__ = (
|
||||
CheckConstraint("status IN ('ACTIVE', 'CLOSED', 'PURGED')", name='ck_biz_test_batch_status'),
|
||||
CheckConstraint(
|
||||
"preview_action IS NULL OR preview_action IN ('ADOPT', 'PURGE')",
|
||||
name='ck_biz_test_batch_preview_action',
|
||||
),
|
||||
{'comment': '测试数据批次'},
|
||||
)
|
||||
|
||||
batch_id = Column(BigInteger, primary_key=True, autoincrement=True)
|
||||
batch_code = Column(String(64), nullable=False, unique=True)
|
||||
batch_name = Column(String(100), nullable=False)
|
||||
status = Column(String(16), nullable=False, server_default='ACTIVE')
|
||||
create_by = Column(String(64), nullable=False, server_default='')
|
||||
create_time = Column(DateTime, nullable=False, default=datetime.now)
|
||||
update_by = Column(String(64), nullable=False, server_default='')
|
||||
update_time = Column(DateTime, nullable=False, default=datetime.now)
|
||||
closed_by = Column(BigInteger, ForeignKey('sys_user.user_id'), nullable=True)
|
||||
closed_at = Column(DateTime, nullable=True)
|
||||
purged_by = Column(BigInteger, ForeignKey('sys_user.user_id'), nullable=True)
|
||||
purged_at = Column(DateTime, nullable=True)
|
||||
purge_summary = Column(Text, nullable=True)
|
||||
preview_action = Column(String(16), nullable=True)
|
||||
preview_token_hash = Column(CHAR(64), nullable=True)
|
||||
preview_scope_hash = Column(CHAR(64), nullable=True)
|
||||
preview_expires_at = Column(DateTime, nullable=True)
|
||||
remark = Column(String(500), nullable=True)
|
||||
|
||||
|
||||
class BizTestBatchUser(Base):
|
||||
"""测试数据批次与用户关联。"""
|
||||
|
||||
__tablename__ = 'biz_test_batch_user'
|
||||
|
||||
batch_id = Column(BigInteger, ForeignKey('biz_test_batch.batch_id'), primary_key=True)
|
||||
user_id = Column(BigInteger, ForeignKey('sys_user.user_id'), primary_key=True)
|
||||
create_by = Column(String(64), nullable=False, server_default='')
|
||||
create_time = Column(DateTime, nullable=False, default=datetime.now)
|
||||
@@ -0,0 +1,116 @@
|
||||
from datetime import datetime
|
||||
from typing import Annotated, Literal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from pydantic.alias_generators import to_camel
|
||||
|
||||
from module_business.domain.enums import TestBatchStatus
|
||||
|
||||
PositiveId = Annotated[int, Field(gt=0)]
|
||||
|
||||
|
||||
class TestBatchApiModel(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
alias_generator=to_camel,
|
||||
from_attributes=True,
|
||||
populate_by_name=True,
|
||||
extra='forbid',
|
||||
)
|
||||
|
||||
|
||||
class TestBatchCreateModel(TestBatchApiModel):
|
||||
batch_name: str = Field(min_length=1, max_length=100)
|
||||
remark: str | None = Field(default=None, max_length=500)
|
||||
|
||||
|
||||
class TestBatchEditModel(TestBatchApiModel):
|
||||
remark: str | None = Field(default=None, max_length=500)
|
||||
|
||||
|
||||
class TestBatchUserAssignModel(TestBatchApiModel):
|
||||
user_ids: list[PositiveId]
|
||||
|
||||
|
||||
class TestBatchModel(TestBatchApiModel):
|
||||
batch_id: PositiveId
|
||||
batch_code: str
|
||||
batch_name: str
|
||||
status: TestBatchStatus
|
||||
remark: str | None = None
|
||||
create_by: str
|
||||
create_time: datetime
|
||||
update_by: str
|
||||
update_time: datetime
|
||||
closed_by: int | None = None
|
||||
closed_at: datetime | None = None
|
||||
purged_by: int | None = None
|
||||
purged_at: datetime | None = None
|
||||
purge_summary: dict[str, int] | None = None
|
||||
|
||||
|
||||
class TestBatchOptionModel(TestBatchApiModel):
|
||||
batch_id: PositiveId
|
||||
batch_code: str
|
||||
batch_name: str
|
||||
status: TestBatchStatus
|
||||
|
||||
|
||||
class BatchImpactModel(TestBatchApiModel):
|
||||
table_name: str
|
||||
label: str
|
||||
count: int = Field(ge=0)
|
||||
keys: list[str]
|
||||
|
||||
|
||||
class TestBatchDetailModel(TestBatchModel):
|
||||
user_ids: list[int]
|
||||
data_summary: list[BatchImpactModel]
|
||||
|
||||
|
||||
class TestBatchPreviewModel(TestBatchApiModel):
|
||||
batch_id: PositiveId
|
||||
batch_name: str
|
||||
preview_token: str
|
||||
expires_at: datetime
|
||||
total_count: int = Field(ge=0)
|
||||
impacts: list[BatchImpactModel]
|
||||
|
||||
|
||||
class PurgePreviewModel(TestBatchPreviewModel):
|
||||
online_purge_allowed: bool
|
||||
online_purge_limit: int = Field(ge=0)
|
||||
blocking_reason: str | None = None
|
||||
|
||||
|
||||
AdoptionRootType = Literal[
|
||||
'strain',
|
||||
'customer',
|
||||
'site',
|
||||
'line',
|
||||
'warehouse',
|
||||
'pallet',
|
||||
'inbound',
|
||||
'filling',
|
||||
'shipment',
|
||||
'usage',
|
||||
'return',
|
||||
]
|
||||
|
||||
|
||||
class AdoptionRootModel(TestBatchApiModel):
|
||||
resource_type: AdoptionRootType
|
||||
resource_ids: list[PositiveId] = Field(min_length=1)
|
||||
|
||||
|
||||
class AdoptionPreviewRequestModel(TestBatchApiModel):
|
||||
roots: list[AdoptionRootModel] = Field(min_length=1)
|
||||
|
||||
|
||||
class AdoptionExecuteRequestModel(AdoptionPreviewRequestModel):
|
||||
batch_name: str = Field(min_length=1, max_length=100)
|
||||
preview_token: str = Field(min_length=32, max_length=128)
|
||||
|
||||
|
||||
class PurgeExecuteRequestModel(TestBatchApiModel):
|
||||
batch_name: str = Field(min_length=1, max_length=100)
|
||||
preview_token: str = Field(min_length=32, max_length=128)
|
||||
Reference in New Issue
Block a user