Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
c8f4921
add battery_capacity_kwh field to match fuel_tank_capacity_gal
zer0stars Apr 1, 2026
38ea9e0
allow manual onboarding when VIN decode is low-confidence
zer0stars Apr 17, 2026
cc5cbf8
add regression test for GWS214 Crown hybrid payload
zer0stars Apr 17, 2026
006d911
disambiguate multi-model japan17vin responses via additional-info
zer0stars Apr 17, 2026
87b06b5
strip parens and prefer model_list standardized name
zer0stars Apr 17, 2026
b62b944
Replace Tableland on-chain device definitions with R2 catalog service
zer0stars Aug 19, 2026
aeb89cf
Path-escape definition ids in catalog/worker URLs
zer0stars Aug 19, 2026
3c69878
Fix catalog doc decoding and nil handling found in verification
zer0stars Aug 20, 2026
5965170
Add opt-in catalog E2E test (CATALOG_E2E_URL)
zer0stars Aug 20, 2026
98a66be
Lint: unused params, duplicate import
zer0stars Aug 20, 2026
7ab18c4
Catalog service: Prometheus metrics + CDN-bypassing read for updates
zer0stars Aug 21, 2026
944f8ad
Lint: preallocate device style response
zer0stars Aug 24, 2026
ed28e91
Fix review findings: nil-404 guards, create exists-guard, metadata wipe
zer0stars Aug 24, 2026
4925c55
fix: prune search documents whose definition left the catalog
zer0stars Aug 24, 2026
0c323f0
fix: prune only definitions that are actually gone, not unindexed ones
zer0stars Aug 25, 2026
b9c2ddd
fix: stop silent write no-ops, decouple the sync page size, fail an e…
zer0stars Aug 25, 2026
cc3bfd2
fix: stale read-modify-write, misleading trx hash, blind metrics, pag…
zer0stars Aug 25, 2026
52daf73
fix: clamp pageSize on the r1 compatibility search too, and use the r…
zer0stars Aug 25, 2026
86f10a0
fix: base deletions on a pinned fresh manifest, not a manufacturer walk
zer0stars Aug 25, 2026
ebb8bdd
fix: correct the pin's rationale, tighten the prune guard, report rea…
zer0stars Aug 25, 2026
28152d9
fix: replace the prune fraction with a flat cap
zer0stars Aug 25, 2026
fc47b58
docs: plan the resolved decode
zer0stars Aug 28, 2026
4ef0bf1
feat(catalog): read vehicle templates instead of flat definitions
zer0stars Aug 28, 2026
675c939
fix(catalog): delete the bulk powertrain tool and its dead write path
zer0stars Aug 28, 2026
9057859
fix(catalog): stop conflating a catalog outage with a missing template
zer0stars Aug 28, 2026
d65f199
fix(decode): stop creating a duplicate definition during a catalog ou…
zer0stars Aug 28, 2026
fec51f9
feat(decode): narrow a template to one trim, or say why not
zer0stars Aug 28, 2026
87e24a2
fix(decode): anchor the vinPattern regex, pin hardwareTemplateId on n…
zer0stars Aug 28, 2026
d315c79
feat(decode): return the matched trim and how confident the match is
zer0stars Aug 28, 2026
1ff1404
fix(decode): plumb drivly's manufacturer code into trim matching
zer0stars Aug 28, 2026
77a8e62
feat(metrics): count VIN decodes by trim match quality
zer0stars Aug 28, 2026
5b3ae53
feat(decode): add match_by and hardware_template_id to DecodeVinResponse
zer0stars Aug 28, 2026
1fcda8d
fix(decode): give a cached decode the same trim answer as a fresh one
zer0stars Aug 28, 2026
3d5aab7
test(matcher): pin that trim selectors are conjunctive
zer0stars Aug 28, 2026
1d08ec6
docs: correct two comments this branch made untrue
zer0stars Aug 28, 2026
c14519b
docs: record what resolved-decode leaves undone and what gates its de…
zer0stars Aug 28, 2026
717a4ca
feat(catalog): write templates to /t/:id instead of the deleted route
zer0stars Aug 30, 2026
5184e47
feat(search): stop indexing Typesense from dd-api; the worker owns it
zer0stars Aug 30, 2026
6aa9826
feat(catalog): fold decoded metadata onto the vocabulary on create
zer0stars Aug 30, 2026
4b2b001
feat(catalog): drop the manifest; read definitions as templates
zer0stars Aug 30, 2026
2dc8955
docs: record the deploy blocker as cleared, and what it cost
zer0stars Aug 30, 2026
254cff2
fix(search): read the worker's per-trim index without panicking
zer0stars Sep 14, 2026
9059dcc
fix(common): never build a definition id the worker rejects
zer0stars Sep 14, 2026
a51eb9f
fix(catalog): treat an absent manufacturer tokenId as unknown, not 0
zer0stars Sep 14, 2026
684018a
fix(catalog): make Create create-only and adopt a concurrently stored…
zer0stars Sep 14, 2026
61d9dff
fix(common): keep every definition id the worker already accepts
zer0stars Sep 14, 2026
d7c8138
fix(search): name each search result for its definition, not its top …
zer0stars Sep 14, 2026
1d63587
test(common): check id building against the manifest's real names
zer0stars Sep 14, 2026
de10c7b
refactor(grpc): remove the device definition create, update and filte…
zer0stars Sep 14, 2026
ede41b8
Merge #311 (battery_capacity_kwh field) into r2-device-definitions
zer0stars Sep 14, 2026
5694b45
Merge #312 (manual onboarding for low-confidence decodes) into r2-dev…
zer0stars Sep 14, 2026
3d619e6
chore: gofmt the #311 field and pin the #312 low-confidence sources
zer0stars Sep 14, 2026
c1a89d1
Answer the model on the cached decode path
zer0stars Sep 15, 2026
cd86b49
Fail the cached decode when the catalog is unreachable
zer0stars Sep 15, 2026
d385be6
Answer an unknown WMI instead of panicking, and honour the caller's c…
zer0stars Sep 15, 2026
dc77a9e
Answer 404, not 500, for an unknown device definition id
zer0stars Sep 15, 2026
6870eb2
Read the template bulk VIN validation actually receives
zer0stars Sep 15, 2026
a336bfc
Refuse a definition id the catalog can never hold
zer0stars Sep 15, 2026
1b96a94
Match trims on the decode that created the definition
zer0stars Sep 15, 2026
0a3db7c
Make the fresh catalog read actually miss the cache
zer0stars Sep 15, 2026
ef70b94
Close the decode's transaction before the catalog round trip
zer0stars Sep 15, 2026
8c4a317
Report a failed device_styles read instead of panicking the decode
zer0stars Sep 19, 2026
73dceb5
Record a failed decode instead of panicking on a nil vendor extra
zer0stars Sep 19, 2026
15122a7
Make the id builder validate its own output at every call site
zer0stars Sep 19, 2026
4eebfbf
Serve a device style the attributes of the trim it actually is
zer0stars Sep 19, 2026
a9781ae
Render style attributes with the shared renderer and a stable order
zer0stars Sep 19, 2026
3638456
search the renamed Typesense collection
zer0stars Sep 22, 2026
4847de3
fix: stop a decode miss from becoming permanent
zer0stars Sep 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions charts/device-definitions-api/templates/secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ metadata:
spec:
data:
- remoteRef:
key: {{ .Release.Namespace }}/definitions/ethereum/rpc_url
secretKey: ETHEREUM_RPC_URL
key: {{ .Release.Namespace }}/definitions/worker/token
secretKey: DEFINITIONS_WORKER_TOKEN
- remoteRef:
key: {{ .Release.Namespace }}/definitions/aws/access_key_id
secretKey: AWS_ACCESS_KEY_ID
- remoteRef:
key: {{ .Release.Namespace }}/definitions/aws/secret_access_key
secretKey: AWS_SECRET_ACCESS_KEY
- remoteRef:
key: {{ .Release.Namespace }}/definitions/kms/key_id
secretKey: KMS_KEY_ID
- remoteRef:
key: {{ .Release.Namespace }}/definitions/db/host
secretKey: DB_HOST
Expand Down Expand Up @@ -77,9 +74,6 @@ spec:
- remoteRef:
key: {{ .Release.Namespace }}/definitions/typesense/apiurl
secretKey: SEARCH_SERVICE_API_URL
- remoteRef:
key: {{ .Release.Namespace }}/definitions/polygonscan/apikey
secretKey: POLYGON_SCAN_API_KEY
- remoteRef:
key: {{ .Release.Namespace }}/definitions/googlesheets/credentials
secretKey: GOOGLE_SHEETS_CREDENTIALS
Expand Down
18 changes: 8 additions & 10 deletions charts/device-definitions-api/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ env:
REDIS_CLUSTER_MODE: true
REDIS_TLS: true
KAFKA_BROKERS: kafka-prod-dimo-kafka-kafka-brokers:9092
ETHEREUM_SEND_TRANSACTION: true
TABLELAND_API_GATEWAY: http://tableland-node-prod.prod.svc.cluster.local:8080/
ETHEREUM_REGISTRY_ADDRESS: '0xFA8beC73cebB9D88FF88a2f75E7D7312f2Fd39EC'
SEARCH_SERVICE_DEVICE_DEFINITION_INDEX: definitions_prod
# One hostname on purpose: definitions-worker is what serves
# definitions.dimo.org, so there is no separate origin to read through.
# A read that must not be served from the edge cache misses it by cache
# key instead -- see fetchTemplateDocFresh's cache-busting parameter.
DEFINITIONS_CATALOG_URL: https://definitions.dimo.org
DEFINITIONS_WORKER_URL: https://definitions.dimo.org
SEARCH_SERVICE_DEVICE_DEFINITION_INDEX: definitions_v2_prod
IDENTITY_API_URL: https://identity-api.dimo.zone/query
ingress:
enabled: true
Expand Down Expand Up @@ -58,9 +61,4 @@ tolerations: []
affinity: {}
podDisruptionBudget:
minAvailable: 1
jobs:
- name: device-definitions-search-sync
schedule: 0 13 * * *
args:
- '-c'
- /device-definitions-api sync-device-definitions-search; CODE=$?; echo "daily device definitions typesense search sync completed"; wget -q --post-data "hello=shutdown" http://localhost:4191/shutdown &> /dev/null; exit $CODE;
jobs: []
18 changes: 8 additions & 10 deletions charts/device-definitions-api/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,13 @@ env:
VINCARIO_API_URL: https://api.vindecoder.eu/3.2
DAT_GROUP_URL: https://www.datgroup.com/myClaim/soap/v2/VehicleIdentificationService
PRIVATE_KEY_MODE: false
ETHEREUM_SEND_TRANSACTION: true
TABLELAND_API_GATEWAY: http://tableland-node-dev.dev.svc.cluster.local:8080/
ETHEREUM_REGISTRY_ADDRESS: '0x5eAA326fB2fc97fAcCe6A79A304876daD0F2e96c'
SEARCH_SERVICE_DEVICE_DEFINITION_INDEX: definitions_dev
# One hostname on purpose: definitions-worker is what serves
# definitions.dev.dimo.org, so there is no separate origin to read through.
# A read that must not be served from the edge cache misses it by cache
# key instead -- see fetchTemplateDocFresh's cache-busting parameter.
DEFINITIONS_CATALOG_URL: https://definitions.dev.dimo.org
DEFINITIONS_WORKER_URL: https://definitions.dev.dimo.org
SEARCH_SERVICE_DEVICE_DEFINITION_INDEX: definitions_v2_dev
IDENTITY_API_URL: https://identity-api.dev.dimo.zone/query
service:
type: ClusterIP
Expand Down Expand Up @@ -119,9 +122,4 @@ serviceMonitor:
path: /metrics
port: mon-http
interval: 30s
jobs:
- name: search-index-load
schedule: 0 0 * * *
args:
- '-c'
- /device-definitions-api sync-device-definitions-search; CODE=$?; echo "weekly typesense mmy search index sync completed"; wget -q --post-data "hello=shutdown" http://localhost:4191/shutdown &> /dev/null; exit $CODE;
jobs: []
33 changes: 16 additions & 17 deletions cmd/device-definitions-api/add_vin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import (

"github.com/DIMO-Network/device-definitions-api/internal/core/common"
"github.com/DIMO-Network/device-definitions-api/internal/infrastructure/gateways"
"github.com/DIMO-Network/device-definitions-api/internal/infrastructure/sender"
"github.com/ethereum/go-ethereum/ethclient"

"github.com/DIMO-Network/device-definitions-api/internal/config"
"github.com/DIMO-Network/device-definitions-api/internal/infrastructure/db/models"
Expand All @@ -32,8 +30,6 @@ import (
type addVINCmd struct {
logger zerolog.Logger
settings config.Settings

sender sender.Sender
}

func (*addVINCmd) Name() string { return "addvin" }
Expand Down Expand Up @@ -61,16 +57,7 @@ func (p *addVINCmd) Execute(ctx context.Context, _ *flag.FlagSet, _ ...interface
pdb := db.NewDbConnectionFromSettings(ctx, &p.settings.DB, true)
pdb.WaitForDB(p.logger)

ethClient, err := ethclient.Dial(p.settings.EthereumRPCURL.String())
if err != nil {
p.logger.Fatal().Err(err).Msg("Failed to create Ethereum client.")
}

chainID, err := ethClient.ChainID(ctx)
if err != nil {
p.logger.Fatal().Err(err).Msg("Couldn't retrieve chain id.")
}
onChainSvc := gateways.NewDeviceDefinitionOnChainService(&p.settings, &p.logger, ethClient, chainID, p.sender, pdb.DBS)
catalogSvc := gateways.NewDeviceDefinitionCatalogService(&p.settings, &p.logger)

vinDecodeNumber, err := models.FindVinNumber(ctx, pdb.DBS().Reader, vin)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
Expand Down Expand Up @@ -117,18 +104,30 @@ func (p *addVINCmd) Execute(ctx context.Context, _ *flag.FlagSet, _ ...interface
return subcommands.ExitFailure
}

manufacturer, err := onChainSvc.GetManufacturer(stringutils.SlugString(wmi.ManufacturerName))
manufacturer, err := catalogSvc.GetManufacturer(stringutils.SlugString(wmi.ManufacturerName))
if err != nil {
fmt.Println(err.Error())
return subcommands.ExitFailure
}
definitionID := common.DeviceDefinitionSlug(stringutils.SlugString(wmi.ManufacturerName), stringutils.SlugString(model), int16(vinNumber.Year))
deviceDefinition, err := onChainSvc.GetDefinitionTableland(ctx, big.NewInt(int64(manufacturer.TokenID)), definitionID)
definitionID, err := common.DeviceDefinitionSlug(stringutils.SlugString(wmi.ManufacturerName), stringutils.SlugString(model), int16(vinNumber.Year))
if err != nil {
// No template can exist at this id, so the lookup below would 404 and
// the row would point at a definition that can never be created.
fmt.Println(err.Error())
return subcommands.ExitFailure
}
deviceDefinition, err := catalogSvc.GetDefinition(ctx, big.NewInt(int64(manufacturer.TokenID)), definitionID)

if err != nil {
fmt.Println(err.Error() + " " + model + " " + strconv.Itoa(vinNumber.Year))
return subcommands.ExitFailure
}
if deviceDefinition == nil {
// (nil, nil) is returned both for a missing definition and for one
// owned by a different manufacturer; dereferencing panics.
fmt.Println("no device definition found for " + definitionID)
return subcommands.ExitFailure
}
vinNumber.DefinitionID = deviceDefinition.ID

err = vinNumber.Insert(ctx, pdb.DBS().Writer, boil.Infer())
Expand Down
2 changes: 0 additions & 2 deletions cmd/device-definitions-api/add_vins_csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/DIMO-Network/device-definitions-api/internal/config"
"github.com/DIMO-Network/device-definitions-api/internal/infrastructure/db/models"
"github.com/DIMO-Network/device-definitions-api/internal/infrastructure/gateways"
"github.com/DIMO-Network/device-definitions-api/internal/infrastructure/sender"
"github.com/DIMO-Network/shared/pkg/db"
"github.com/DIMO-Network/shared/pkg/logfields"
vinutils "github.com/DIMO-Network/shared/pkg/vin"
Expand All @@ -28,7 +27,6 @@ type addVINsCSVCmd struct {
logger zerolog.Logger
settings config.Settings

sender sender.Sender
identity gateways.IdentityAPI
}

Expand Down
166 changes: 0 additions & 166 deletions cmd/device-definitions-api/bulk_update_powertrain.go

This file was deleted.

32 changes: 13 additions & 19 deletions cmd/device-definitions-api/decode_vin.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
vinutil "github.com/DIMO-Network/shared/pkg/vin"
"github.com/aarondl/null/v8"
"github.com/aarondl/sqlboiler/v4/boil"
"github.com/ethereum/go-ethereum/ethclient"

"github.com/goccy/go-json"

Expand Down Expand Up @@ -181,7 +180,16 @@ func (p *decodeVINCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...interf
dbVin.ManufacturerName = vinInfo.Make
}
dbVin.DatgroupData = null.JSONFrom(vinInfo.Raw)
dbVin.DefinitionID = common.DeviceDefinitionSlug(vinInfo.Make, vinInfo.Model, int16(vinInfo.Year))
definitionID, errID := common.DeviceDefinitionSlug(vinInfo.Make, vinInfo.Model, int16(vinInfo.Year))
if errID != nil {
// Inserting the row anyway is what the validator's contract
// forbids: every later DecodeVIN of this VIN would read the
// cached row, look its definition up in the catalog, 404
// forever, and answer with an empty trim and match quality.
fmt.Println("skipping, no definition id can be built: " + errID.Error())
continue
}
dbVin.DefinitionID = definitionID
dbVin.DecodeProvider = null.StringFrom(string(vinInfo.Source))
// todo future change to add field with StyleName

Expand Down Expand Up @@ -254,7 +262,7 @@ func readVINFile(filename string) ([]string, error) {
return values, nil
}

func instantiateVINDecodingSvc(ctx context.Context, settings *config.Settings, logger *zerolog.Logger, pdb db.Store) services.VINDecodingService {
func instantiateVINDecodingSvc(_ context.Context, settings *config.Settings, logger *zerolog.Logger, pdb db.Store) services.VINDecodingService {
datAPI := gateways.NewDATGroupAPIService(settings, logger)
drivlyAPI := gateways.NewDrivlyAPIService(settings)
vincarioAPI := gateways.NewVincarioAPIService(settings, logger)
Expand All @@ -265,21 +273,7 @@ func instantiateVINDecodingSvc(ctx context.Context, settings *config.Settings, l
return services.NewVINDecodingService(drivlyAPI, vincarioAPI, nil, logger, nil, datAPI, pdb.DBS, jp17vinAPI, carvxAPI, elevaAPI)
}

send, err := createSender(ctx, settings, logger)
if err != nil {
logger.Fatal().Err(err).Msg("Failed to create sender.")
}

ethClient, err := ethclient.Dial(settings.EthereumRPCURL.String())
if err != nil {
logger.Fatal().Err(err).Msg("Failed to create Ethereum client.")
}

chainID, err := ethClient.ChainID(ctx)
if err != nil {
logger.Fatal().Err(err).Msg("Couldn't retrieve chain id.")
}
deviceDefinitionOnChainService := gateways.NewDeviceDefinitionOnChainService(settings, logger, ethClient, chainID, send, pdb.DBS)
deviceDefinitionCatalogService := gateways.NewDeviceDefinitionCatalogService(settings, logger)

return services.NewVINDecodingService(drivlyAPI, vincarioAPI, nil, logger, deviceDefinitionOnChainService, datAPI, pdb.DBS, jp17vinAPI, carvxAPI, elevaAPI)
return services.NewVINDecodingService(drivlyAPI, vincarioAPI, nil, logger, deviceDefinitionCatalogService, datAPI, pdb.DBS, jp17vinAPI, carvxAPI, elevaAPI)
}
Loading
Loading