feat: device identity fields + device_catalog category (no-fabrication import support) - #121
Merged
Merged
Conversation
… battery/weight and brand country Prepares the engine for the Google Play supported-devices / device-catalog import without inventing values: anything a source does not state stays null. - smartphone, tablet, watch, pda: optional model_numbers, codenames (lists of unique non-empty strings) and release_date_precision (day|month|year|year_estimated, null = unspecified), stored, seeded, serialized and dumped. - smartphone: battery_mah and weight_g are no longer required (null allowed, range checks kept when present); the battery score is null when the capacity is unknown. - brand: country is optional; a brand without one lives under brand/unknown/. - new unscored category device_catalog (data/device_catalog/<brand>/<slug>.json, no year folder), served at /v1/device-catalog: identity fields, optional Play Console specs (ram_gb, soc FK, soc_raw, gpu_raw, screen_resolution, screen_density_dpi, android_sdk_min/max), release_year only together with release_year_source, form_factor vs device_type_guess, promoted_to. - category registry is now 13 entries; scope strings derive the count.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What / why
TechAPI is about to import Google Play's public
supported_devices.csv(brand, marketing name, codename, model number) and a Play Console device-catalog export (RAM, form factor, SoC, GPU, screen, SDK levels). Neither source has battery, weight, brand country, or a reliable launch date. Play's min SDK only gives an upper bound on the launch year. This PR changes the engine so those records can be stored without filling the gaps with guesses.No-fabrication rule: if a source does not state a value, it stays
null(or[]for lists). Nothing is estimated to satisfy a required field.Changes
Identity fields on smartphone / tablet / watch / pda
model_numbers: list[str](default[]), e.g.SM-S938Ncodenames: list[str](default[]), e.g.pa3qrelease_date_precision: str | None, one ofday | month | year | year_estimated(null= unspecified, which covers all existing records)These are stored, seeded, serialized in
SmartphoneRead/MobileDeviceRead, and dumped.Relaxed required fields
battery_mahandweight_gare no longer inPHONE_REQUIRED.nullis allowed, and the range checks still run when a value is present. The model and schema are nullable now. If capacity is unknown, the battery sub-score isnull(it used to crash).countryis optional. A brand without a country lives underbrand/unknown/<slug>.json, and the folder is enforced. When a country is present, the ISO alpha-2 check and the folder match still apply.New category
device_catalog(unscored, identity-only)data/device_catalog/<brand>/<slug>.json. There is no year folder, because the release date is unknown by definition. The path check exists for this category only.GET /v1/device-catalog(filters:brand,form_factor,base_model_slug; sort:name,android_sdk_min) andGET /v1/device-catalog/{slug}. Dumped as collectiondevice-catalog. A SoC change also re-dumps it, since entries embed a SoC summary.slug,name,brand(FK),source_urls,verifiedbase_model_slug,model_numbers,codenames,marketing_namesform_factor: only when a source states itdevice_type_guess: explicitly a heuristic guess, same vocabulary asform_factor(phone|tablet|watch|tv|other)ram_gb,soc(FK slug,nullif unresolved),soc_raw,gpu_raw,screen_resolution("1080x2400"),screen_density_dpi,android_sdk_min,android_sdk_maxrelease_yeartogether withrelease_year_source(model_code | record): both or neitherpromoted_to:"<smartphone|tablet|watch|pda>/<slug>"form_factoranddevice_type_guessuse the enums aboveandroid_sdk_max >= android_sdk_minscreen_resolutionmust match theWxHformatsocandbrandmust point to existing recordspromoted_tomust be well-formedRegistry
CATEGORIESnow has 13 entries. TheN/N categoriesscope strings indump_checkandintegrity_checknow countCATEGORIESinstead of hardcoding 12.Validation results (local, against TechAPI
developdata)ruff check app tests: passmypy app: pass (115 files)python -m app.validate: passpytest --cov=app --cov-fail-under=60: all tests pass, 78.1% coveragetests/unit/test_validate_identity.py: field rules, catalog path/required/enum/range rules, brand withcountrynull or omittedtests/integration/test_device_catalog.py: endpoints, plus a self-contained validate → seed → API → dump round trip covering a country-less brand, a phone with null battery/weight, a tablet with identity fields, and catalog entries with and without a SoCbattery_mah/weight_gonSmartphoneRead.Follow-ups (outside this PR)
app/validate.pymirror needs the same relaxations and the new rules. A ready diff is prepared separately for the TechAPI side.device_catalogas a category with no domain rules, so those entries are never scored green (domain_rules_unavailable).