Skip to content

feat(products): pick tags from a curated corpus in the product form - #647

Open
alukach wants to merge 5 commits into
mainfrom
feat/product-tags
Open

alukach wants to merge 5 commits into
mainfrom
feat/product-tags

Conversation

@alukach

@alukach alukach commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Product owners can now set a product's tags from the product form, in both create and edit mode, choosing from a curated corpus kept in a new DynamoDB table.

closes #177

What changes

  • New table sc-{stage}-tags (deploy/lib/database-construct.ts), partition key tag_id, which is the tag string itself (the same string stored in product.metadata.tags). Each row is just { tag_id }. The Vercel role gets grantReadData only, because the app never writes the corpus. Curation happens outside the app.
  • TagsTable.listAll() (src/lib/clients/database/tags.ts) scans the table with pagination and returns the tags sorted.
  • TagPicker (src/components/features/products/TagPicker.tsx) shows the chosen tags as removable chips beside an "Edit tags" button. The button opens a Radix Themes Popover that lists every corpus tag as a checkbox, with a box to filter them, so people can browse the whole list without guessing what to type. Each chosen tag is submitted as its own tags form value from a hidden input next to its chip. It is wired into ProductCreationForm as a custom field under Description, and both pages pass the corpus in as tagOptions.
  • Server enforcement (src/lib/actions/products.ts): createProduct and updateProduct read formData.getAll("tags"), dedupe it, and reject any tag outside the corpus with a tags field error. A tag the product already carries is accepted even after it leaves the corpus. This follows the same legacy-drift rule as visibility: editing the title shouldn't fail on a tag nobody chose today.
  • Tag cleanup and seeding: scripts/clean-tags.ts <stage> reads every product's free-text tags, cleans them, and builds the corpus from the result (see Tag cleanup below). It previews by default; APPLY=1 rewrites each product's metadata.tags to its cleaned tags and puts the corpus into sc-{stage}-tags. init-local creates the table and seeds it from the fixture products' tags.

Rollout

  1. Deploy the CDK stack, which creates the table and the grant.
  2. Run AWS_REGION=us-west-2 npx tsx scripts/clean-tags.ts prod and review the preview: the corpus, the dropped tags, and each product whose tags change. Production is in us-west-2; the script defaults to us-east-1 like the others in scripts/. Adjust ALIASES and KEEP in the script until the result is right.
  3. Run it again with APPLY=1. This rewrites product tags, so take an on-demand backup of sc-prod-products first. Until then the corpus is empty, and the popover shows "No tags to choose from yet."

Tag cleanup

Production's products carry 416 distinct free-text tags. Many are the same tag in another case or spelling (PMTiles and pmtiles; ftw and fieldsoftheworld), several tags typed as one string (#overturemaps #roads #riyadh …), places below country level (14 Spanish regions, German state codes from the fiboa datasets), or noise (test, foo, --, an empty tag, and geospatial and open data, which are true of everything on Source).

scripts/clean-tags.ts lowercases each tag, strips #, splits combined tags, maps synonyms, typos and places to one canonical tag through ALIASES, and drops noise. A canonical tag joins the corpus when two or more products carry it, or when it is in KEEP (countries, plus elevation, machine learning, time series, forests and hydrology). Each product keeps only its cleaned tags that are in the corpus.

Run against the production counts (TABLE=1 npx tsx scripts/clean-tags.ts --counts counts.txt): 416 raw tags → 196 cleaned → 136 in corpus. Counts are products per tag. They are built from per-tag counts, so a product that had two spellings of one tag counts twice and some totals run slightly high; the <stage> run counts per product exactly.

The 136 tags in the corpus, by number of products
Tag Products
field boundaries 113
geoparquet 101
pmtiles 85
agriculture 75
vector 72
fiboa 59
fields of the world 58
spain 30
fieldscapes 27
sentinel-2 25
segmentation 20
weather 18
climate 17
germany 17
zarr 17
building footprints 14
energy 13
hydrology 13
sigpac 13
crop type 12
crops 12
land cover 12
raster 12
united states 12
cog 11
satellite imagery 11
overture maps 10
saudi arabia 10
biodiversity 9
forecasting 9
parquet 9
sentinel-1 9
admin boundaries 8
places 8
precipitation 8
conservation 7
elevation 7
forests 7
india 7
labels 7
machine learning 7
carbon 6
cloud native 6
icechunk 6
japan 6
land use 6
solar 6
stac 6
transportation 6
vegetation 6
embeddings 5
global 5
landsat 5
ocean 5
openstreetmap 5
planetscope 5
sar 5
ai 4
carbon dioxide removal 4
flatgeobuf 4
foundation models 4
gapfilled 4
lidar 4
modis 4
natural gas 4
nhd 4
remote sensing 4
tanzania 4
wildfire 4
youthmappers 4
aerosols 3
atmosphere 3
belgium 3
canada 3
census 3
cer 3
clay 3
cloud 3
ecology 3
fisheries 3
image classification 3
imagery 3
netherlands 3
radar 3
reanalysis 3
regression 3
rwanda 3
africa 2
austria 2
bathymetry 2
brazil 2
computer vision 2
duckdb 2
eurocrops 2
exports 2
flood detection 2
geopackage 2
geostationary 2
google 2
h3 2
hls 2
imports 2
invekos 2
latvia 2
marine debris 2
microsoft 2
monitoring 2
naip 2
neb 2
noaa 2
object detection 2
observations 2
slovenia 2
switzerland 2
tiles 2
time series 2
united kingdom 2
usda 2
wetlands 2
wildlife 2
antarctica 1
cambodia 1
croatia 1
czechia 1
denmark 1
estonia 1
europe 1
finland 1
france 1
ireland 1
luxembourg 1
new zealand 1
portugal 1
slovakia 1
sweden 1
vietnam 1
Dropped because only one product carries them (60)
Tag Products
american bollworms 1
attribution benchmark 1
bioregionalisation 1
brp 1
catalog 1
copernicus 1
corridors 1
csv 1
digitaltwin 1
disaster risk 1
dwr 1
ee-mrio 1
egms 1
eia 1
environment 1
environmental data 1
epa 1
equity 1
esa 1
exiobase 1
ferc 1
finance 1
foodsecurity 1
foodsystems 1
fude 1
gdal 1
geocoding 1
geos 1
geozarr 1
goes 1
government 1
hex 1
historical 1
human footprint 1
iceberg 1
imputation 1
jpss 1
justice 1
landscape elements 1
meiji era 1
metop 1
nasa 1
neon 1
ngff 1
nsta 1
pink bollworms 1
plodiny 1
png 1
policy 1
population 1
procurement 1
property data 1
protected areas 1
realtime 1
sahara 1
snow 1
supplychain 1
synthetic data 1
terrestrial 1
usgs 1

Keep any of these by adding it to KEEP, or merge it into a corpus tag in ALIASES.

Every tag that changes (295 rows; unchanged tags appear only in the corpus list)
Count Before After Notes
30 ftw fields of the world Merged
28 fieldsoftheworld fields of the world Merged
10 geospatial — Dropped: noise
5 boundaries admin boundaries Merged
4 satellite satellite imagery Merged
4 overture overture maps Merged
4 landsat 8 landsat Merged
4 foundational model foundation models Merged
3 nhd nhd, hydrology Split into several tags
3 ml machine learning Merged
3 imagery satellite imagery Merged
3 (empty) — Dropped: noise
2 usa united states Merged
2 uk united kingdom Merged
2 sentinel2 sentinel-2 Merged
2 opendata — Dropped: noise
2 karnataka india Merged
2 forecast forecasting Merged
2 fieldboundaries field boundaries Merged
2 field boundary field boundaries Merged
2 field — Dropped: noise
2 earth — Dropped: noise
2 dem elevation Merged
2 crop crops Merged
2 cloud optimised geotiff cog Merged
2 climate change climate Merged
2 cdr carbon dioxide removal Merged
2 california united states Merged
2 buildings building footprints Merged
2 building footprint building footprints Merged
2 admin admin boundaries Merged
2 Sentinel2 sentinel-2 Merged
2 PMTiles pmtiles Normalized (case, #)
2 Japan japan Normalized (case, #)
2 COG cog Normalized (case, #)
2 AI ai Normalized (case, #)
2 #geoparquet #aois #places #dataset #riyadh #geospatial #overturemaps #saudiarabia geoparquet, places, saudi arabia, overture maps Split into several tags
1 youthmasppers youthmappers Merged
1 years — Dropped: noise
1 xai machine learning Merged
1 wheat crops Merged
1 wbd hydrology Merged
1 waterways hydrology Merged
1 watershed boundaries hydrology Merged
1 water hydrology Merged
1 wadhwaniai — Dropped: noise
1 vegetation cover vegetation Merged
1 valencia spain Merged
1 usgs — Dropped: on one product only
1 us united states Merged
1 tropical storm weather Merged
1 trees forests Merged
1 topography elevation Merged
1 timeseries time series Merged
1 tiff raster Merged
1 ticks biodiversity Merged
1 th germany Merged
1 testrepo12 — Dropped: noise
1 test unidata netcdf — Dropped: noise
1 test — Dropped: noise
1 terrestrial — Dropped: on one product only
1 temperature weather Merged
1 taxi zones transportation Merged
1 tamsat precipitation Merged
1 synthetic data — Dropped: on one product only
1 swiss switzerland Merged
1 supplychain — Dropped: on one product only
1 street level imagery imagery Merged
1 static — Dropped: noise
1 state — Dropped: noise
1 stac-geoparquet stac, geoparquet Split into several tags
1 sst ocean Merged
1 species distribution model biodiversity Merged
1 southern ocean ocean Merged
1 south fork eel river united states Merged
1 source — Dropped: noise
1 solar maps solar Merged
1 snow — Dropped: on one product only
1 slovenia fiboa field boundaries krms gerk geoparquet vector pmtiles slovenia, fiboa, field boundaries, geoparquet, vector, pmtiles Split into several tags
1 sl germany Merged
1 sixpac sigpac Merged
1 sh germany Merged
1 sfer — Dropped: noise
1 self-supervised machine learning Merged
1 sax — Dropped: noise
1 saudiarabia saudi arabia Merged
1 sahara — Dropped: on one product only
1 riyadh saudi arabia Merged
1 remotesensing remote sensing Merged
1 reanalysis data reanalysis Merged
1 realtime — Dropped: on one product only
1 rainfall radar precipitation, radar Split into several tags
1 pv solar Merged
1 public-data — Dropped: noise
1 public — Dropped: noise
1 protected areas — Dropped: on one product only
1 property data — Dropped: on one product only
1 procurement — Dropped: on one product only
1 population — Dropped: on one product only
1 polygon — Dropped: noise
1 political boundaries admin boundaries Merged
1 policy — Dropped: on one product only
1 pois places Merged
1 poi places Merged
1 png — Dropped: on one product only
1 pmtiles gtfs pmtiles, transportation Split into several tags
1 plodiny — Dropped: on one product only
1 planet fusion planetscope Merged
1 pink bollworms — Dropped: on one product only
1 photovoltaic solar Merged
1 perspective images imagery Merged
1 pacificspatial — Dropped: noise
1 overturemaps overture maps Merged
1 osm openstreetmap Merged
1 open data — Dropped: noise
1 ome — Dropped: noise
1 oil production energy Merged
1 observation observations Merged
1 nyc united states Merged
1 nwp forecasting, weather Split into several tags
1 nsta — Dropped: on one product only
1 nrw germany Merged
1 ngff — Dropped: on one product only
1 netherlands fiboa field boundaries aan geoparquet vector pmtiles netherlands, fiboa, field boundaries, geoparquet, vector, pmtiles Split into several tags
1 net zero carbon Merged
1 neon — Dropped: on one product only
1 nds germany Merged
1 navarra spain Merged
1 natural gas production natural gas Merged
1 national hydrology dataset nhd, hydrology Split into several tags
1 nasa — Dropped: on one product only
1 mv germany Merged
1 multitemporal time series Merged
1 mrms precipitation Merged
1 misc — Dropped: noise
1 metop — Dropped: on one product only
1 metadata — Dropped: noise
1 maize crops Merged
1 madrid spain Merged
1 luxembourg fiboa field flik boundaries geoparquet vector pmtiles luxembourg, fiboa, field boundaries, geoparquet, vector, pmtiles Split into several tags
1 lulc land cover, land use Split into several tags
1 lowcoder — Dropped: noise
1 live fuel moisture wildfire Merged
1 lidar 3dtiles mago lidar Merged
1 landscape elements — Dropped: on one product only
1 landcover land cover Merged
1 land-use and land-cover change land cover, land use Split into several tags
1 land — Dropped: noise
1 lacuna — Dropped: noise
1 ksrsac india Merged
1 karnatak india Merged
1 justice — Dropped: on one product only
1 jpss — Dropped: on one product only
1 ireland fiboa field boundarie geoparquet vector pmtiles ireland, fiboa, field boundaries, geoparquet, vector, pmtiles Split into several tags
1 insolation solar Merged
1 imputation — Dropped: on one product only
1 imerg precipitation Merged
1 image — Dropped: noise
1 iceberg — Dropped: on one product only
1 hydrography hydrology Merged
1 human footprint — Dropped: on one product only
1 historical — Dropped: on one product only
1 hex — Dropped: on one product only
1 height elevation Merged
1 hcat — Dropped: noise
1 havasu united states Merged
1 hamburg germany Merged
1 groundwater quality hydrology Merged
1 groundtruthed labels Merged
1 ground-truthed labels Merged
1 ground-truth labels Merged
1 gpm precipitation Merged
1 government — Dropped: on one product only
1 goes — Dropped: on one product only
1 geozarr — Dropped: on one product only
1 geos — Dropped: on one product only
1 geocoding — Dropped: on one product only
1 geo spatial — Dropped: noise
1 gdal — Dropped: on one product only
1 galicia spain Merged
1 fude — Dropped: on one product only
1 forest carbon forests, carbon Split into several tags
1 forest forests Merged
1 forecasts forecasting Merged
1 foodsystems — Dropped: on one product only
1 foodsecurity — Dropped: on one product only
1 foo — Dropped: noise
1 flowlines hydrology Merged
1 flanders belgium Merged
1 fishbase fisheries Merged
1 fish fisheries Merged
1 fire wildfire Merged
1 finance — Dropped: on one product only
1 ferc — Dropped: on one product only
1 farmland agriculture Merged
1 extremadura spain Merged
1 euhvd — Dropped: noise
1 esa — Dropped: on one product only
1 era5 reanalysis, climate Split into several tags
1 equity — Dropped: on one product only
1 epa — Dropped: on one product only
1 environmental data — Dropped: on one product only
1 environment — Dropped: on one product only
1 energy use by fuel energy Merged
1 energy use energy Merged
1 energy transition energy Merged
1 energy production energy Merged
1 energy efficiency energy Merged
1 energy demand by sector energy Merged
1 energy demand energy Merged
1 emissions carbon Merged
1 embedding embeddings Merged
1 electricity generation energy Merged
1 electricity energy Merged
1 eia — Dropped: on one product only
1 eatch monitoring monitoring Merged
1 dwr — Dropped: on one product only
1 dust aerosols Merged
1 drone imagery Merged
1 disaster risk — Dropped: on one product only
1 digitaltwin — Dropped: on one product only
1 deforestation forests Merged
1 deep learning machine learning Merged
1 dataset — Dropped: noise
1 czech czechia Merged
1 csv — Dropped: on one product only
1 croptype crop type Merged
1 county — Dropped: noise
1 countries — Dropped: noise
1 cotton crops Merged
1 corridors — Dropped: on one product only
1 contour elevation Merged
1 coal energy Merged
1 cloud-native cloud native Merged
1 cdl crop type, united states Split into several tags
1 catalonia spain Merged
1 catalog — Dropped: on one product only
1 castillalamancha spain Merged
1 castile and leon spain Merged
1 carbon emissions carbon Merged
1 cantabria spain Merged
1 canary islands spain Merged
1 businesses places Merged
1 building building footprints Merged
1 brp — Dropped: on one product only
1 bremen germany Merged
1 boundary vector agriculture field boundaries, vector, agriculture Split into several tags
1 blore india Merged
1 bioregionalisation — Dropped: on one product only
1 biomass forests Merged
1 belgium wallonia fiboa field boundaries geoparquet vector pmtiles belgium, fiboa, field boundaries, geoparquet, vector, pmtiles Split into several tags
1 beetles biodiversity Merged
1 bb germany Merged
1 basque spain Merged
1 balearic islands spain Merged
1 attribution benchmark — Dropped: on one product only
1 arc — Dropped: noise
1 aragon spain Merged
1 aquatics ocean Merged
1 aois — Dropped: noise
1 andalusia spain Merged
1 andalucía spain Merged
1 analysis — Dropped: noise
1 amx — Dropped: noise
1 american bollworms — Dropped: on one product only
1 aerosol aerosols Merged
1 Trees forests Merged
1 Tottori japan Merged
1 Topographic Map elevation Merged
1 Sentinel2 mosaics cloud-free global cog raster sentinel-2, global, cog, raster Split into several tags
1 PMTiles FlatGeobuf pmtiles, flatgeobuf Split into several tags
1 Meiji era — Dropped: on one product only
1 Forest forests Merged
1 EXIOBASE — Dropped: on one product only
1 EU europe Merged
1 EGMS — Dropped: on one product only
1 EE-MRIO — Dropped: on one product only
1 DEM elevation Merged
1 Copernicus — Dropped: on one product only
1 Cloud-Native cloud native Merged
1 3d tiles lidar Merged
1 -- — Dropped: noise
1 #waterways hydrology Merged
1 #vector vector Normalized (case, #)
1 #tif raster Merged
1 #stac stac Normalized (case, #)
1 #sentinel #satellite #imagery #cog #aws #remotesensing #saudiarabia #tabaqat sentinel-2, satellite imagery, cog, remote sensing, saudi arabia Split into several tags
1 #riyadh #satellite #rgb #cog #2024 saudi arabia, satellite imagery, cog Split into several tags
1 #raster raster Normalized (case, #)
1 #pmtiles #cng #saudiarabia #sentinel #tabaqat #aws pmtiles, cloud native, saudi arabia, sentinel-2 Split into several tags
1 #parquet parquet Normalized (case, #)
1 #overturemaps #roads #riyadh #osm #pmtiles #cng #tabaqat overture maps, transportation, saudi arabia, openstreetmap, pmtiles, cloud native Split into several tags
1 #overturemaps #roads #pmtiles #cng #osm #tabaqat #saudiarabia overture maps, transportation, pmtiles, cloud native, openstreetmap, saudi arabia Split into several tags
1 #geospatial #ksa #riyadh #geoparquet #places #pois saudi arabia, geoparquet, places Split into several tags
1 #cbam #climate reanalysis reanalysis, climate Split into several tags

Decisions worth a second look

  • Which tags survive is a judgement call. The ALIASES and KEEP lists in scripts/clean-tags.ts encode it, and the tables above show the result. Calls most worth checking: boundaries and admin become admin boundaries; satellite and imagery merge into satellite imagery; agencies on one product (nasa, usgs, esa, epa) are dropped while those on two or more (noaa, usda, cer, neb) stay.
  • No admin UI for the corpus. Tags are added in the AWS console or CLI for now. An admin page is the natural follow-up if curation becomes frequent.
  • updateProduct always replaces metadata.tags with what the form submits. It can't skip the write when no tags field arrives, because a product with every chip removed submits no tags field at all, and that has to clear them. The product form is the only caller and always renders the picker.
  • No cap on tag count. The docs used to promise "up to 20". Nothing enforced that before and nothing does now, so I dropped the claim from the docs instead of inventing a limit.
  • Popover picker instead of a datalist or a combobox library. The first version used a native <datalist>, but its dropdown ignored the theme and hid the list until you typed. Of the alternatives (every tag as a toggle chip, or a popover like GitHub's label picker), the popover keeps the field compact and uses only components Radix Themes already ships. The list renders every tag without virtualisation, which is fine to a few hundred tags; past that it should be virtualised (marked with a ponytail: comment).

Stories

On this branch's Storybook deploy:

The Filtering story, with the popover open and filtered to tags containing "c":

TagPicker with the popover open

Docs

  • docs/using-source/create-a-data-product.md described tags as "Comma-separated, up to 20 tags", which is now stale. Updated in docs.source.coop#39.
  • docs/about-source/core-concepts.md ("Tags and Discoverability") still holds: it says what tags are for, not how they are entered.
  • public/llms.txt doesn't mention tags, and this adds no public endpoint. Checked the data-proxy ADRs: tags have no bearing on authorization, credentials, or federation.

Testing

  • npm run test for src/lib/actions/products.test.ts and src/components/features/products/TagPicker.test.tsx passes locally (30 tests), and so does npm run type-check. npm run lint reports nothing in the changed files.
  • The action tests cover create saving corpus tags, rejecting unknown ones, and not reading the tag table when no tags are sent, and update saving corpus tags, rejecting unknown ones, and keeping a retired tag the product already had.
  • TagPicker.test.tsx covers removing a chip, and the popover filtering case-insensitively and toggling a tag on and off.

🤖 Generated with Claude Code

The product form, in create and edit mode, gets a Tags field: a text input that suggests tags from a new sc-{stage}-tags table (keyed by tag_id, the tag itself) and shows chosen tags as removable chips. createProduct and updateProduct save the submitted tags to metadata.tags and reject any outside the corpus, except tags the product already carries, so a tag retired from the corpus never blocks an edit to some other field.

The app only reads the corpus, so the Vercel role gets read access to the table and nothing more. scripts/seed-tags.ts seeds it from the tags products already have, and init-local creates and seeds it locally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
source-coop-ui Ready Ready Preview Oct 9, 2026 12:27am UTC
source-cooperative Ready Ready Preview Oct 9, 2026 12:27am UTC

Request Review

@claude

claude Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @alukach's task in 14s —— View job


✅ No blocking issues — safe to merge.

I read the diff for correctness and security. Nothing blocks the merge, and I didn't run the tests or type-check.

  • Server enforcement: parseTags dedupes the submitted tags and checks them against the corpus plus the product's current tags, so it can't be bypassed by crafting form data. Skipping the corpus lookup when no tags are submitted is safe.
  • Clearing tags: updateProduct writes metadata.tags on every call, so removing every chip clears the tags, as the description says.
  • Pagination cache: listAll() paginates through cachedSend, whose cache key includes ExclusiveStartKey. Pages don't collide.
  • IAM: the Vercel role gets read-only access to the tags table, which matches the corpus being curated outside the app.
  • init-local: the table is created, dropped and seeded consistently.

Simplify (ponytail)

  • src/components/features/products/TagPicker.tsx: Partial<ControlProps> is spread onto the Button only. If DynamicForm doesn't need it there, drop the spread and the extra prop type.
  • src/app/(app)/products/new/page.tsx: await tagsTable.listAll() runs inline after the other awaits. Starting it in an existing Promise.all, as the edit page does, avoids a serial round trip.

Docs

  • The description names the affected doc and links the PR that updates it: docs.source.coop#39, for the stale "up to 20 tags" line.
  • It says core-concepts.md and llms.txt still hold and why.
  • It says the data-proxy ADRs were checked and tags don't touch them.

Nothing is missing here.


💰 Estimated review cost: $0.21 · 0m13s · 6 turns

The browser's datalist dropdown wasn't styled by the theme and hid the corpus until you typed. Chosen tags now show as removable chips beside an "Edit tags" button, which opens a popover listing every corpus tag as a checkbox, with a box to filter them. Submission and server-side validation are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alukach added a commit to source-cooperative/docs.source.coop that referenced this pull request Oct 8, 2026
The tag field now opens a list to tick tags from rather than suggesting them as you type (source-cooperative/source.coop#647).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
parseTags now returns either the tags or the form error naming those outside the corpus, so the one-use unknownTagsState wrapper goes away. The popover's tag list gets a note on its ceiling: it renders every tag, which is fine to a few hundred and wants virtualising past that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scripts/clean-tags.ts replaces seed-tags.ts. Instead of copying every free-text tag into the corpus, it lowercases them, strips `#`, splits tags that hold several, maps synonyms, typos and sub-national places to one canonical tag, and drops noise. A canonical tag joins the corpus when two or more products carry it, or when it is on a keep-list (countries and a few broad topics). Each product then keeps only its cleaned tags that made the corpus.

It previews by default and writes only with APPLY=1. Given the `uniq -c` counts of production's tags (--counts), it previews from those instead of DynamoDB, and TABLE=1 adds a before/after table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving a product without tags no longer reads the tags table, so a create or edit that sets no tags doesn't depend on that table existing. The picker's toggle also updates from the latest tags rather than the ones it rendered with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alukach

alukach commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

@tylere please review the tag corpus table in this PR description and the tags that we will be dropping, I'd be curious to hear your thoughts

@tylere

tylere commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

While I am fully on board with (e.g. tag cleanup), I think there are aspects that would benefit from future discussion.
Some examples:

  • What is the mechanism by which users can suggest new tags?
  • Would it be beneficial to group/order tags in some way to guide users in selecting appropriate tags?
    • Examples
      • feature type (e.g. field-boundaries, land-parcels, admin-units)
      • methodology (e.g. remote-sensing, machine-learning, foundation-model)
      • format (e.g. cog, zarr, pmtiles)
      • domain (e.g. climate, weather, oceanography, agriculture, conservation, medical)
      • temporal frequency (e.g. hourly, daily, yearly)
  • Should we give some indication of a tags popularity?

This branch was successfully deployed

2 active deployments
Preview – source-cooperative — 19932460 Deployed Oct 9, 2026 by vercel[bot]
Preview – source-coop-ui — 19932460 Deployed Oct 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Proposed Feature] Product Tags administration

2 participants