Removing objective_thread_pitch from scopes_info

This commit is contained in:
Ian Roddis committed 2026-08-17 15:48:50 -03:00
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)
)
-2
View File
@@ -37,7 +37,6 @@ async def create(
magnification_max: float | None = None,
model_suffix: str | None = None,
objective_lens_diameter_mm: float | None = None,
objective_thread_pitch: str | None = None,
) -> ScopeInfo:
info = ScopeInfo(
augmented_part_id=augmented_part_id,
@@ -45,7 +44,6 @@ async def create(
magnification_max=magnification_max,
model_suffix=model_suffix,
objective_lens_diameter_mm=objective_lens_diameter_mm,
objective_thread_pitch=objective_thread_pitch,
)
db.add(info)
await db.commit()
-5
View File
@@ -32,8 +32,3 @@ class ScopeInfo(Base):
objective_lens_diameter_mm: Mapped[float | None] = mapped_column(
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
)
-1
View File
@@ -6,7 +6,6 @@ class ScopeInfoBase(BaseModel):
magnification_max: float | None = None
model_suffix: str | None = None
objective_lens_diameter_mm: float | None = None
objective_thread_pitch: str | None = None
class ScopeInfoRead(ScopeInfoBase):
-3
View File
@@ -15,7 +15,6 @@ sub_part_type → SubPartType (get-or-create under "Scope"
product_number → AugmentedPart.sku (also the upsert / fit-lookup key)
magnification_min / _max → ScopeInfo
objective_lens_diameter_mm → ScopeInfo (descriptive only, no attachment point)
objective_thread_pitch → ScopeInfo
ocular_outer_diameter_mm → StaticConnection + AttachmentPoint "Ocular"
objective_thread → ISO/UNC thread + AttachmentPoint "Objective"
ocular_fit → Fit: scope's Ocular AP ↔ referenced part's first AP
@@ -75,7 +74,6 @@ EXPECTED_COLUMNS = [
"url",
"ocular_outer_diameter_mm",
"ocular_fit",
"objective_thread_pitch",
"objective_thread",
"objective_fit",
]
@@ -321,7 +319,6 @@ async def import_scopes(db: AsyncSession, rows: list[dict]) -> ScopeImportResult
magnification_max=_num(row.get("magnification_max")),
model_suffix=model_suffix,
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
-2
View File
@@ -51,8 +51,6 @@
<td>
{% if 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 %}
</td>
{% for ct in column_types %}
@@ -50,7 +50,6 @@
{{ scope_info.objective_lens_diameter_mm }} mm
{% else %}—{% endif %}
</dd>
<dt>Objective thread</dt><dd>{{ scope_info.objective_thread_pitch or "—" }}</dd>
</dl>
</div>
{% endif %}
-2
View File
@@ -38,7 +38,6 @@ async def _seed_part_with_fit(db):
augmented_part_id=scope.id,
magnification_min=3,
magnification_max=18,
objective_thread_pitch="M52x0.75",
)
)
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
assert "Alpha 3-18x50" in body
assert "ALP-318" in body
assert "M52x0.75" in body # scope info
assert "Objective" in body # attachment point
# Fits are shown (the other part in the fit)
assert "Flip cover 50mm" in body
-4
View File
@@ -49,7 +49,6 @@ async def _seed_guide_data(db):
magnification_min=3,
magnification_max=18,
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 "Flip cover 50mm" in body # a matching part in a fit column
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
@@ -294,9 +292,7 @@ async def test_scopes_page_renders_objective_attachment_point_thread(
resp = await client.get("/scopes")
assert resp.status_code == 200
body = resp.text
# The attachment point's thread spec wins over ScopeInfo.objective_thread_pitch.
assert "M44.0×0.5" in body
assert "M52x0.75" not in body
@pytest.mark.asyncio
-3
View File
@@ -26,7 +26,6 @@ HEADERS = [
"url",
"ocular_outer_diameter_mm",
"ocular_fit",
"objective_thread_pitch",
"objective_thread",
"objective_fit",
]
@@ -59,7 +58,6 @@ def _scope_row(**overrides):
"url": "https://example.com/viper",
"ocular_outer_diameter_mm": 40,
"ocular_fit": None,
"objective_thread_pitch": "0.75",
"objective_thread": "M40x0.75",
"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.model_suffix == "PST"
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)
by_label = {}