places: a description the community shared is credited to the TREK community

A community description laid over OSM details or an index row showed up as
OpenStreetMap under ODbL, or as the place's own website. It now has a source of
its own, community, credited as TREK Community under CC BY 4.0, like the
service publishes it.
This commit is contained in:
Maurice
2026-10-30 22:28:15 +01:00
parent 7f2a3b6039
commit ce5ec7132f
6 changed files with 41 additions and 2 deletions
@@ -402,6 +402,8 @@ function descriptionSourceLabel(
return 'Wikivoyage'
case 'wikipedia':
return 'Wikipedia'
case 'community':
return 'TREK Community'
case 'website':
try {
return new URL(sourceUrl || '').hostname.replace(/^www\./, '')
+5 -1
View File
@@ -36,7 +36,11 @@ export function withCommunityValues(
out.opening_periods = hours.opening_periods;
}
}
if (values.description?.text) out.summary = values.description.text;
if (values.description?.text) {
out.summary = values.description.text;
// The details panel credits it to the community, not to OpenStreetMap.
out.summary_source = 'community';
}
if (typeof values.community.version === 'number') out.community_version = values.community.version;
return out;
}
@@ -705,10 +705,14 @@ export class PlaceEnrichmentService {
if (!this.maps.trekPlacesEnabled()) return null;
try {
const got = (
(await trekPlacesById(placeId.slice(5))) as { description?: { text?: string; sourceUrl?: string } } | null
(await trekPlacesById(placeId.slice(5))) as {
description?: { text?: string; sourceUrl?: string; source?: string };
} | null
)?.description;
const text = typeof got?.text === 'string' ? got.text.trim() : '';
if (!text) return null;
// A description installations shared and review published, laid over the index row.
if (got?.source === 'community') return { text, source: 'community', sourceUrl: null, license: 'CC BY 4.0' };
// Through the same allow-list a place's website goes through: this
// becomes an href on the client, and the value comes from whatever the
// configured index answered with. Anything but http(s) loses the link and
@@ -739,6 +743,9 @@ export class PlaceEnrichmentService {
// OpenStreetMap first: it costs nothing, it is already fetched, and a
// description someone wrote into the map data beats a generated blurb.
const osmSummary = typeof details?.summary === 'string' ? details.summary.trim() : '';
if (osmSummary && details?.summary_source === 'community') {
return { text: osmSummary, source: 'community', sourceUrl: null, license: 'CC BY 4.0' };
}
if (osmSummary && details?.source === 'openstreetmap') {
return {
text: osmSummary,
@@ -41,6 +41,7 @@ describe('community values on OSM details', () => {
expect(got).toMatchObject({
phone: '+81 6 6440 3855',
summary: 'A tower of two linked blocks.',
summary_source: 'community',
community_version: 3,
name: 'Umeda Sky Building',
});
@@ -281,6 +281,29 @@ describe('description source order', () => {
expect(bare.description).toMatchObject({ source: 'google', sourceUrl: 'https://maps.google.com/x' });
});
it('ENRICH-075b: a description installations shared is credited to the TREK community, not to OpenStreetMap', async () => {
const maps = mapsStub({
details: vi.fn(async () => ({
place: {
source: 'openstreetmap',
summary: 'An Asian restaurant in Evershagen.',
summary_source: 'community',
osm_url: 'https://osm.org/n/1',
},
})),
fetchWikiExtractFor: vi.fn(async () => EXTRACT),
});
const out = await make(maps).enrich(1, OSM_REQ);
expect(out.description).toEqual({
text: 'An Asian restaurant in Evershagen.',
source: 'community',
sourceUrl: null,
license: 'CC BY 4.0',
});
});
it('ENRICH-075: keeps the OpenStreetMap description ahead of everything', async () => {
const maps = mapsStub({
details: vi.fn(async () => ({
+2
View File
@@ -185,6 +185,8 @@ export const placeDescriptionSourceSchema = z.enum([
'wikipedia',
/** Quoted from the place's own site, via the TREK Places API. */
'website',
/** Written by a TREK user, shared by an installation and checked before it was published. */
'community',
]);
export type PlaceDescriptionSource = z.infer<typeof placeDescriptionSourceSchema>;