Removing objective_thread_pitch from scopes_info
This commit is contained in:
1 parent
067ddffbe5
commit
292830ae0f
10 files changed
+29
-23
No files matched your search
@@ -0,0 +1,29 @@
|
|||||||
|
"""drop_objective_thread_pitch_from_scope_infos
|
||||||
|
|
||||||
|
Revision ID: 235d823a56ee
|
||||||
|
Revises: 04425ce3d4d5
|
||||||
|
Create Date: 2026-08-17 15:18:26.763831
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = "235d823a56ee"
|
||||||
|
down_revision: Union[str, None] = "04425ce3d4d5"
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
with op.batch_alter_table("scope_infos", schema=None) as batch_op:
|
||||||
|
batch_op.drop_column("objective_thread_pitch")
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
with op.batch_alter_table("scope_infos", schema=None) as batch_op:
|
||||||
|
batch_op.add_column(
|
||||||
|
sa.Column("objective_thread_pitch", sa.String(), nullable=True)
|
||||||
|
)
|
||||||
@@ -37,7 +37,6 @@ async def create(
|
|||||||
magnification_max: float | None = None,
|
magnification_max: float | None = None,
|
||||||
model_suffix: str | None = None,
|
model_suffix: str | None = None,
|
||||||
objective_lens_diameter_mm: float | None = None,
|
objective_lens_diameter_mm: float | None = None,
|
||||||
objective_thread_pitch: str | None = None,
|
|
||||||
) -> ScopeInfo:
|
) -> ScopeInfo:
|
||||||
info = ScopeInfo(
|
info = ScopeInfo(
|
||||||
augmented_part_id=augmented_part_id,
|
augmented_part_id=augmented_part_id,
|
||||||
@@ -45,7 +44,6 @@ async def create(
|
|||||||
magnification_max=magnification_max,
|
magnification_max=magnification_max,
|
||||||
model_suffix=model_suffix,
|
model_suffix=model_suffix,
|
||||||
objective_lens_diameter_mm=objective_lens_diameter_mm,
|
objective_lens_diameter_mm=objective_lens_diameter_mm,
|
||||||
objective_thread_pitch=objective_thread_pitch,
|
|
||||||
)
|
)
|
||||||
db.add(info)
|
db.add(info)
|
||||||
await db.commit()
|
await db.commit()
|
||||||
|
|||||||
@@ -32,8 +32,3 @@ class ScopeInfo(Base):
|
|||||||
objective_lens_diameter_mm: Mapped[float | None] = mapped_column(
|
objective_lens_diameter_mm: Mapped[float | None] = mapped_column(
|
||||||
Float, nullable=True, default=None
|
Float, nullable=True, default=None
|
||||||
)
|
)
|
||||||
# Kept as the raw string from the sheet (e.g. "0.75", "1/16") so no precision
|
|
||||||
# or notation is lost; the parsed thread lives on its own AttachmentPoint.
|
|
||||||
objective_thread_pitch: Mapped[str | None] = mapped_column(
|
|
||||||
String, nullable=True, default=None
|
|
||||||
)
|
|
||||||
@@ -6,7 +6,6 @@ class ScopeInfoBase(BaseModel):
|
|||||||
magnification_max: float | None = None
|
magnification_max: float | None = None
|
||||||
model_suffix: str | None = None
|
model_suffix: str | None = None
|
||||||
objective_lens_diameter_mm: float | None = None
|
objective_lens_diameter_mm: float | None = None
|
||||||
objective_thread_pitch: str | None = None
|
|
||||||
|
|
||||||
|
|
||||||
class ScopeInfoRead(ScopeInfoBase):
|
class ScopeInfoRead(ScopeInfoBase):
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ sub_part_type → SubPartType (get-or-create under "Scope"
|
|||||||
product_number → AugmentedPart.sku (also the upsert / fit-lookup key)
|
product_number → AugmentedPart.sku (also the upsert / fit-lookup key)
|
||||||
magnification_min / _max → ScopeInfo
|
magnification_min / _max → ScopeInfo
|
||||||
objective_lens_diameter_mm → ScopeInfo (descriptive only, no attachment point)
|
objective_lens_diameter_mm → ScopeInfo (descriptive only, no attachment point)
|
||||||
objective_thread_pitch → ScopeInfo
|
|
||||||
ocular_outer_diameter_mm → StaticConnection + AttachmentPoint "Ocular"
|
ocular_outer_diameter_mm → StaticConnection + AttachmentPoint "Ocular"
|
||||||
objective_thread → ISO/UNC thread + AttachmentPoint "Objective"
|
objective_thread → ISO/UNC thread + AttachmentPoint "Objective"
|
||||||
ocular_fit → Fit: scope's Ocular AP ↔ referenced part's first AP
|
ocular_fit → Fit: scope's Ocular AP ↔ referenced part's first AP
|
||||||
@@ -75,7 +74,6 @@ EXPECTED_COLUMNS = [
|
|||||||
"url",
|
"url",
|
||||||
"ocular_outer_diameter_mm",
|
"ocular_outer_diameter_mm",
|
||||||
"ocular_fit",
|
"ocular_fit",
|
||||||
"objective_thread_pitch",
|
|
||||||
"objective_thread",
|
"objective_thread",
|
||||||
"objective_fit",
|
"objective_fit",
|
||||||
]
|
]
|
||||||
@@ -321,7 +319,6 @@ async def import_scopes(db: AsyncSession, rows: list[dict]) -> ScopeImportResult
|
|||||||
magnification_max=_num(row.get("magnification_max")),
|
magnification_max=_num(row.get("magnification_max")),
|
||||||
model_suffix=model_suffix,
|
model_suffix=model_suffix,
|
||||||
objective_lens_diameter_mm=_num(row.get("objective_lens_diameter_mm")),
|
objective_lens_diameter_mm=_num(row.get("objective_lens_diameter_mm")),
|
||||||
objective_thread_pitch=_text(row.get("objective_thread_pitch")),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Rebuild attachment points from scratch so re-imports stay idempotent
|
# Rebuild attachment points from scratch so re-imports stay idempotent
|
||||||
|
|||||||
@@ -51,8 +51,6 @@
|
|||||||
<td>
|
<td>
|
||||||
{% if row.objective_attachment_point %}
|
{% if row.objective_attachment_point %}
|
||||||
{{ connection_spec(row.objective_attachment_point) }}
|
{{ connection_spec(row.objective_attachment_point) }}
|
||||||
{% elif info and info.objective_thread_pitch %}
|
|
||||||
{{ info.objective_thread_pitch }}
|
|
||||||
{% else %}<span class="muted">—</span>{% endif %}
|
{% else %}<span class="muted">—</span>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
{% for ct in column_types %}
|
{% for ct in column_types %}
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
{{ scope_info.objective_lens_diameter_mm }} mm
|
{{ scope_info.objective_lens_diameter_mm }} mm
|
||||||
{% else %}—{% endif %}
|
{% else %}—{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
<dt>Objective thread</dt><dd>{{ scope_info.objective_thread_pitch or "—" }}</dd>
|
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ async def _seed_part_with_fit(db):
|
|||||||
augmented_part_id=scope.id,
|
augmented_part_id=scope.id,
|
||||||
magnification_min=3,
|
magnification_min=3,
|
||||||
magnification_max=18,
|
magnification_max=18,
|
||||||
objective_thread_pitch="M52x0.75",
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ap_s = AttachmentPoint(augmented_part_id=scope.id, attachment_point_name_id=apn.id)
|
ap_s = AttachmentPoint(augmented_part_id=scope.id, attachment_point_name_id=apn.id)
|
||||||
@@ -80,7 +79,6 @@ async def test_detail_shows_attributes_and_fits_readonly(
|
|||||||
# Attributes
|
# Attributes
|
||||||
assert "Alpha 3-18x50" in body
|
assert "Alpha 3-18x50" in body
|
||||||
assert "ALP-318" in body
|
assert "ALP-318" in body
|
||||||
assert "M52x0.75" in body # scope info
|
|
||||||
assert "Objective" in body # attachment point
|
assert "Objective" in body # attachment point
|
||||||
# Fits are shown (the other part in the fit)
|
# Fits are shown (the other part in the fit)
|
||||||
assert "Flip cover 50mm" in body
|
assert "Flip cover 50mm" in body
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ async def _seed_guide_data(db):
|
|||||||
magnification_min=3,
|
magnification_min=3,
|
||||||
magnification_max=18,
|
magnification_max=18,
|
||||||
objective_lens_diameter_mm=50,
|
objective_lens_diameter_mm=50,
|
||||||
objective_thread_pitch="M52x0.75",
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -222,7 +221,6 @@ async def test_scopes_page_renders_rows_and_fits(
|
|||||||
assert "Alpha 3-18x50" in body # scope row
|
assert "Alpha 3-18x50" in body # scope row
|
||||||
assert "Flip cover 50mm" in body # a matching part in a fit column
|
assert "Flip cover 50mm" in body # a matching part in a fit column
|
||||||
assert "fit-badge-exact" in body # the exact fit badge
|
assert "fit-badge-exact" in body # the exact fit badge
|
||||||
assert "M52x0.75" in body # scope info: objective thread
|
|
||||||
assert "3-18" in body # magnification range, integral values un-padded
|
assert "3-18" in body # magnification range, integral values un-padded
|
||||||
|
|
||||||
|
|
||||||
@@ -294,9 +292,7 @@ async def test_scopes_page_renders_objective_attachment_point_thread(
|
|||||||
resp = await client.get("/scopes")
|
resp = await client.get("/scopes")
|
||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
body = resp.text
|
body = resp.text
|
||||||
# The attachment point's thread spec wins over ScopeInfo.objective_thread_pitch.
|
|
||||||
assert "M44.0×0.5" in body
|
assert "M44.0×0.5" in body
|
||||||
assert "M52x0.75" not in body
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ HEADERS = [
|
|||||||
"url",
|
"url",
|
||||||
"ocular_outer_diameter_mm",
|
"ocular_outer_diameter_mm",
|
||||||
"ocular_fit",
|
"ocular_fit",
|
||||||
"objective_thread_pitch",
|
|
||||||
"objective_thread",
|
"objective_thread",
|
||||||
"objective_fit",
|
"objective_fit",
|
||||||
]
|
]
|
||||||
@@ -59,7 +58,6 @@ def _scope_row(**overrides):
|
|||||||
"url": "https://example.com/viper",
|
"url": "https://example.com/viper",
|
||||||
"ocular_outer_diameter_mm": 40,
|
"ocular_outer_diameter_mm": 40,
|
||||||
"ocular_fit": None,
|
"ocular_fit": None,
|
||||||
"objective_thread_pitch": "0.75",
|
|
||||||
"objective_thread": "M40x0.75",
|
"objective_thread": "M40x0.75",
|
||||||
"objective_fit": None,
|
"objective_fit": None,
|
||||||
}
|
}
|
||||||
@@ -142,7 +140,6 @@ async def test_import_creates_scope_with_info_and_attachment_points(db_sessionma
|
|||||||
assert info.magnification_max == 25
|
assert info.magnification_max == 25
|
||||||
assert info.model_suffix == "PST"
|
assert info.model_suffix == "PST"
|
||||||
assert info.objective_lens_diameter_mm == 56
|
assert info.objective_lens_diameter_mm == 56
|
||||||
assert info.objective_thread_pitch == "0.75"
|
|
||||||
|
|
||||||
aps = await attachment_point_crud.list_for_augmented_part(db, part.id)
|
aps = await attachment_point_crud.list_for_augmented_part(db, part.id)
|
||||||
by_label = {}
|
by_label = {}
|
||||||
|
|||||||
Reference in new issue
Block a user