Skip to content

Conversation

@AmarTrebinjac
Copy link
Contributor

@AmarTrebinjac AmarTrebinjac commented Nov 18, 2025

After a lot of back and forth we decided that we are going to use Mapbox API instead of seeded data, due to the data we got being very low quality.

I removed the timezone and ranking for two reasons:

  1. RFC doesn't mention how or if we are using these at all
  2. Mapbox API doesn't provide timezones, and does its own ranking when searching, so redundant for us.

ranking: number;

@Column({ type: 'text', nullable: true })
@Index('IDX_dataset_location_externalId')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added index since we are now querying it on profile save

@pulumi
Copy link

pulumi bot commented Nov 18, 2025

🍹 The Update (preview) for dailydotdev/api/prod (at f1f1732) was successful.

Resource Changes

    Name                                                   Type                           Operation
~   vpc-native-validate-active-users-cron                  kubernetes:batch/v1:CronJob    update
~   vpc-native-generic-referral-reminder-cron              kubernetes:batch/v1:CronJob    update
~   vpc-native-personalized-digest-deployment              kubernetes:apps/v1:Deployment  update
~   vpc-native-update-source-tag-view-cron                 kubernetes:batch/v1:CronJob    update
~   vpc-native-post-analytics-clickhouse-cron              kubernetes:batch/v1:CronJob    update
~   vpc-native-update-trending-cron                        kubernetes:batch/v1:CronJob    update
~   vpc-native-update-tag-recommendations-cron             kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-stale-user-transactions-cron          kubernetes:batch/v1:CronJob    update
-   vpc-native-api-db-migration-ce7d5dd7                   kubernetes:batch/v1:Job        delete
+   vpc-native-api-db-migration-cfb95f72                   kubernetes:batch/v1:Job        create
~   vpc-native-update-tags-str-cron                        kubernetes:batch/v1:CronJob    update
~   vpc-native-hourly-notification-cron                    kubernetes:batch/v1:CronJob    update
~   vpc-native-check-analytics-report-cron                 kubernetes:batch/v1:CronJob    update
~   vpc-native-daily-digest-cron                           kubernetes:batch/v1:CronJob    update
~   vpc-native-private-deployment                          kubernetes:apps/v1:Deployment  update
~   vpc-native-clean-zombie-images-cron                    kubernetes:batch/v1:CronJob    update
~   vpc-native-deployment                                  kubernetes:apps/v1:Deployment  update
~   vpc-native-clean-gifted-plus-cron                      kubernetes:batch/v1:CronJob    update
~   vpc-native-update-source-public-threshold-cron         kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-users-cron                     kubernetes:batch/v1:CronJob    update
-   vpc-native-api-clickhouse-migration-ce7d5dd7           kubernetes:batch/v1:Job        delete
~   vpc-native-calculate-top-readers-cron                  kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-user-companies-cron            kubernetes:batch/v1:CronJob    update
~   vpc-native-generate-search-invites-cron                kubernetes:batch/v1:CronJob    update
~   vpc-native-temporal-deployment                         kubernetes:apps/v1:Deployment  update
~   vpc-native-sync-subscription-with-cio-cron             kubernetes:batch/v1:CronJob    update
~   vpc-native-update-highlighted-views-cron               kubernetes:batch/v1:CronJob    update
~   vpc-native-post-analytics-history-day-clickhouse-cron  kubernetes:batch/v1:CronJob    update
+   vpc-native-api-clickhouse-migration-cfb95f72           kubernetes:batch/v1:Job        create
~   vpc-native-update-views-cron                           kubernetes:batch/v1:CronJob    update
~   vpc-native-ws-deployment                               kubernetes:apps/v1:Deployment  update
~   vpc-native-personalized-digest-cron                    kubernetes:batch/v1:CronJob    update
~   vpc-native-bg-deployment                               kubernetes:apps/v1:Deployment  update
~   vpc-native-update-current-streak-cron                  kubernetes:batch/v1:CronJob    update
+-  vpc-native-k8s-secret                                  kubernetes:core/v1:Secret      create-replacement

let mapboxGeocodingUrl = `${process.env.MAPBOX_GEOCODING_URL}?q=${encodeURIComponent(externalId)}&access_token=${process.env.MAPBOX_ACCESS_TOKEN}`;

if (process.env.NODE_ENV === 'production') {
mapboxGeocodingUrl += '&permanent=true';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to use this prop to be allowed to save locations locally.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to add this as a comment, it will be forgotten

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could also use URL instead of string concat for all the other params, much less error prone

const response = await fetch(mapboxUrl);

if (!response.ok) {
return [];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we wanna throw an error here or just return empty? Cause if the user starts typing again it will trigger the endpoint again, and then we might have an OK response.

@AmarTrebinjac AmarTrebinjac marked this pull request as ready for review November 19, 2025 11:44
@AmarTrebinjac AmarTrebinjac requested review from a team and capJavert as code owners November 19, 2025 11:44
const response = await fetch(mapboxGeocodingUrl);

if (!response.ok) {
throw new Error('Mapbox API error');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what type of error would be appropriate here?

Copy link
Contributor

@capJavert capJavert Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error is fine, it will be 5xx, but maybe you want to add alerts if you think its necessary we know when it fails.

Also with 3party integrations we usually use Garmr for automatic retries, failover and so on so ideally you add that. Garmr will automatically notifiy on the channel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this added alerts:

        ctx.log.error(
          { error },
          'Failed to fetch location autocomplete from Mapbox',
        );

Is there something specific we need to do to hook it up to our slack channel?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you hook up garmr there are alerts for it automatically so you don't need to do anything

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as for log, it does not send all logs to slack, that would be so spammy 😆 you have to set manual alert for it, I can show you, but as said, garmr should be enough here without manual ctx.log.error call

Copy link
Contributor

@capJavert capJavert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments, blocking stuff is around adding Garmr when interacting with mapbox. Since with Garmr you get reporting and better error and retries handling for free.

return await importEntity(con, params.entity);
}

await importEntity(con, 'DatasetLocation');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also remove seeds then?

externalLocationId: z.preprocess(
(val) => (val === '' ? null : val),
z.string().uuid().nullable().optional().default(null),
z.string().nullable().optional().default(null),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is nullish which is shorthand for nullable and optional

import type { DataSource } from 'typeorm/data-source';
import { DatasetLocation } from './DatasetLocation';

export interface MapboxContext {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's move this to common or integrations, like we have for other 3party stuff, entity folder is plagued with dependency cycles so it would ideally be as clean as possible to avoid new cycles imports

let mapboxGeocodingUrl = `${process.env.MAPBOX_GEOCODING_URL}?q=${encodeURIComponent(externalId)}&access_token=${process.env.MAPBOX_ACCESS_TOKEN}`;

if (process.env.NODE_ENV === 'production') {
mapboxGeocodingUrl += '&permanent=true';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to add this as a comment, it will be forgotten

let mapboxGeocodingUrl = `${process.env.MAPBOX_GEOCODING_URL}?q=${encodeURIComponent(externalId)}&access_token=${process.env.MAPBOX_ACCESS_TOKEN}`;

if (process.env.NODE_ENV === 'production') {
mapboxGeocodingUrl += '&permanent=true';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could also use URL instead of string concat for all the other params, much less error prone

const response = await fetch(mapboxGeocodingUrl);

if (!response.ok) {
throw new Error('Mapbox API error');
Copy link
Contributor

@capJavert capJavert Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error is fine, it will be 5xx, but maybe you want to add alerts if you think its necessary we know when it fails.

Also with 3party integrations we usually use Garmr for automatic retries, failover and so on so ideally you add that. Garmr will automatically notifiy on the channel.

const readmeHtml = markdown.render(data.readme || '');

try {
const formProps = excludeProperties(data, ['externalLocationId']);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had discussion for excludeProperties multiple times before and yes, pro is you can just exclude only one field you need, but ideally I would rather specifically do delete data.externalLocationId here or remove it inside externalLocationId, I don't see the point of this helper personally

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Thought I'd use it since we already have it, but I can just delete the prop as well. I'm not very opinionated 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its just bad in every way, performance wise as well, excludeProperties will iterate over all properties of an object to find one to delete, where delete will just do it 😆

The one in boot is also there for legacy reasons :hidethepain:

},
retryOpts: {
maxAttempts: 3,
backoff: 1000,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will wait for 1000ms after each retry so if we hit rate limit and it keeps failing it will delay any request that calls this for 3+ seconds?

Just making sure its what you want?

@AmarTrebinjac AmarTrebinjac merged commit 42f7535 into main Nov 19, 2025
9 checks passed
@AmarTrebinjac AmarTrebinjac deleted the ENG-62 branch November 19, 2025 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants