Skip to content

Feature/3574 timebound access docs#3928

Draft
HannesDS wants to merge 25 commits into
mainfrom
feature/3574-timebound-access-docs
Draft

Feature/3574 timebound access docs#3928
HannesDS wants to merge 25 commits into
mainfrom
feature/3574-timebound-access-docs

Conversation

@HannesDS

Copy link
Copy Markdown
Collaborator
  • Update the release notes document if needed in the release notes.
  • When updating the UI please provide screenshots or videos to the reviewers.
  • Updated sample data so the new feature can be easily tested.

Update the documentation for feature #3754 timebound access as well as the release notes.

HannesDS and others added 25 commits July 16, 2026 08:23
We made the backend return new objects for
input ports and users my requests and pending requests
  The backend split input ports into a link plus time-bound access
  requests (ADR-0021) and now reports an InputPortStatus (pending,
  approved, denied, expired) alongside a renewal status. This adapts
  the frontend and seed data to that model.

  - Add a Status column to the consumer and producer input-port
    tables with a tag for renewal pending, renewal declined, or
    expiring soon, plus an Expiry date column (blank while
    pending/denied, 'Permanent Access' when open-ended, else the date).
  - Migrate the input-port display path from DecisionStatus to
    InputPortStatus so expired grants render correctly.
  - Add an id to the user input-port response so a pending action can
    be matched back to its output-port row.
  - Seed all seven access states for John Scientist from both the
    consumer and producer perspective.
  - Fix renewal_status to require a prior grant, not just a non-
    approved latest request, so first-time pending/denied requests
    no longer show a false renewal tag.
  - Split RenewalTag into RenewalTag (renewal-status only) and
    IsExpiringSoonTag per review comment.
  - Move access-duration-type lookup onto OutputPort and restore the
    PERMANENT short-circuit; it must never require a DB row, since
    access_durations rows aren't guaranteed to exist for every type.
  - Add a check constraint enforcing days is set iff time_bound.
  - Seed an 'expiring soon' input port so the new tag is testable.
  - Add a renewal_status test suite and auto-provision the matching
    AccessDuration row from OutputPortFactory so existing tests don't
    need updating
  Renewing access previously reused the "request new access"
  endpoint and service method (existing links were silently
  updated instead of rejected), which was flagged in review as
  conflating two distinct actions.

  Split AbstractDataProductService into add/renew methods and
  add a dedicated renew endpoint on both the data products and
  explorations routers. Surface it as a Renew button in the
  input-port table for links that are expired or expiring soon.
  Color was overloaded across the status badge and renewal/expiry
  tags, making the real status hard to scan. Now only the status
  badge carries color (expired is red, requested is grey); renewal
  and expiring-soon indicators are neutral icon+text instead of
  colored tags. 'Expiring soon' moved to the Expiry date column,
  and the renewal tag is hidden when status is already 'Requested'
  since that's redundant for end users.
  Producers could only end a consumer's access by hard-deleting the
  input port link, and denying a request doubled as a way to pull
  already-approved access, which didn't reflect what actually happened.
  Consumers had the same ambiguity: cancelling a pending request and
  giving up approved access were both the same hard delete.

  Introduce revoke (ends an approved grant, available to either side)
  and cancel (withdraws a still-pending request, consumer-only) as
  first-class, non-destructive actions. Revoke sets revoked_at /
  revoked_by_id on the approved request without touching its decision;
  cancel moves the request's decision to a new CANCELLED value on a
  dedicated InputPortRequestDecision enum, kept separate from the
  shared DecisionStatus used by other approval flows. Deny is now
  scoped to pending requests only.

  recompute_status and current_request were reworked so a pending
  request never hides a link's real prior outcome (Expired/Revoked/
  Denied) on its own - only a first-ever request, or a fresh re-ask
  after a plain denial, still reports Pending, since nothing else
  would otherwise signal that a decision is awaited.

  The UI only ever exposes revoke and cancel. The original hard-delete
  routes (producer-side /remove, consumer-side DELETE) stay alive in
  the backend as a deliberate two-way door, unreferenced by any button,
  in case fully removing an input port ever turns out to be genuinely
  needed.

  Updates ADR-0021 and adds test coverage for the full status/renewal
  display matrix on both backend and frontend.
  The 'My Requests' history showed 'Available' for input port access
  that had already been revoked, because the request's decision stays
  APPROVED forever (a historical fact) while revocation is tracked
  separately via revoked_at. Status helpers now check revoked_at
  before falling back to the decision label.

  Also removes an unreachable status assignment in approve_request
  (immediately overwritten by recompute_status() in both callers), an
  orphaned pre-ADR-0021 schema pair still importing the shared
  DecisionStatus enum, and a input_port_count filter that compared
  against DecisionStatus instead of InputPortStatus.
Add a daily (+ on-startup) task that recomputes link status for
  approved/expired links and emits the access-ended event once a grant's
  window has passed. An expiry_event_sent flag guarantees delivery: it's
  only set on a successful webhook call, so a failed delivery is retried
  on the next run, and it's cleared whenever a new grant is approved.
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.

2 participants