Feat/site image links#196
Open
vharmain wants to merge 5 commits into
Open
Conversation
Sports sites can now carry an :images collection (url, alt-text, copyright,
description) edited through a new "Kuvat" tab. Images live in an external
image bank; LIPAS stores only the CC BY 4.0 metadata.
Access is gated by a new :site/edit-images privilege. The :images-manager
role grants it without :site/save-api, so its holders can only save revisions
whose diff is limited to :images; enforced in backend/core/check-permissions!
by comparing the incoming doc against the persisted one (ignoring event-date
and search-meta noise).
Initial rollout: Loimaa (city-code 430) assigns the role to designated users.
Later cities either add the privilege to an existing broader role or get a
role assignment. :images surfaces in Public API v2 (not v1, which is frozen).
Elasticsearch mapping declares :images as {:enabled false} — existing strict
indices must be recreated or have the field added before deploy, otherwise
saves with :images populated will fail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…fallback
Per the external image-links requirement spec ("Täydentävä
vaatimusmäärittely"), a bare URL is no longer accepted:
- :alt-text and :copyright (source/owner) are now required with at least
one non-empty translation; enforced in the malli schema (validates the
internal save API and surfaces in v2 OpenAPI) and in the edit dialog,
whose save button stays disabled until URL + alt-text + copyright are
filled.
- Image URLs must be https:// — http images would be blocked as mixed
content on the https-served LIPAS anyway. Single source of truth in
lipas.schema.sports-sites.images/valid-url?, shared by schema and UI.
- Failed image loads (broken links) no longer render the browser's
broken-image icon: the dialog preview and the hover popper swap in a
neutral text placeholder via on-error.
- Schema descriptions and docs/site-images.md now spell out the API
consumer obligations: embed/hotlink images from the source URL, no
caching or re-hosting, so source-side takedowns (GDPR/copyright)
propagate immediately. Updating the official API Terms of Use remains a
legal/process task outside this repo.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Previously :site/save-api holders (e.g. city-managers) could write :images through the regular save endpoint even though the UI never offered it to them — pilot containment relied on the UI alone. check-permissions! now enforces both directions of the diff against the persisted revision: - :images changed (or present on a new site) -> :site/edit-images required - anything else changed -> :site/save-api required, as before Saves that merely round-trip unchanged images (the UI posts the full document) need no images privilege, so regular editing of sites that already have images keeps working. Rolling the feature out to a new municipality remains a pure role assignment: grant :images-manager (on top of existing editor rights) with the municipality's city-code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two bugs hid persisted images from the UI even though the API returned them: - The ::display-site sub builds its map field-by-field and never included :images, so the read-only tab always rendered an empty table — and view-images? gating made the tab invisible to users without :site/edit-images even when the site had images. - The images editor caches its table state from :value once at mount (r/with-let), so entering edit mode after viewing the empty read-only tab kept the stale empty state. Key the component by lipas-id, mode and value so state re-derives whenever the source changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The canonical lipas-id schema was [:int {:min 0}] (allowed 0), while the
jobs payload schema required pos-int?. lipas-ids come from a Postgres
sequence and are always >= 1; every save enqueues an analysis job
validated as pos-int?, so a site with lipas-id 0 could never be saved.
The looser front gate let mg/generate produce :lipas-id 0, which passed
the sports-site schema but failed the job schema at enqueue time -> 500
(seed-dependent flake in HTTP-save tests, e.g. the images-manager test).
- Tighten the canonical schema to [:int {:min 1}].
- Repoint the ad-hoc [:lipas-id :int] / [:vector :int] / [:set [:int
{:min 0}]] usages at the canonical #'sports-sites-schema/lipas-id
(jobs payload, bulk-operations, ptv handler/workbench, ptv schema,
users schema, frontend map route) instead of re-spelling it.
- Update lipas-id-test: 0 is now invalid, matching the contract the jobs
layer always enforced.
Two deliberate exceptions:
- ptv/ai.clj keeps inline :int: it feeds malli.json-schema/transform for
Gemini structured output, where a var ref becomes a JSON-schema $ref
that Gemini's schema subset doesn't support (verified).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 53ee6cd)
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.
Pilot for Loimaa to add externally hosted images to sports sites