feat: a public notes page per release, for clients
On the releases page, «Página pública» (owners and admins) opens a
secret link to a page with the release's notes, readable without an
account, also for private projects: the notes written, or the draft
from its finished tickets while there are none (without repeating the
title the page already shows). The link can be copied, renewed (the old
one stops working) or withdrawn. Stored in Mongo (`release_note_shares`).
API: shareReleaseNotes / unshareReleaseNotes / releaseNotesShare,
publicReleaseNotes(token); GET/PUT/DELETE /api/releases/{id}/public-notes,
GET /api/shared/release-notes/{token}. Web: /notes/:token.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,3 +39,26 @@ export interface SharedDashboard {
|
||||
| null;
|
||||
activity: { day: string; count: number }[] | null;
|
||||
}
|
||||
|
||||
/** A release's public notes link (owners and admins). */
|
||||
export interface ReleaseNotesShare {
|
||||
releaseId: string;
|
||||
/** The secret of the link: /notes/{token}. */
|
||||
token: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
/** A release's notes, for anyone with its link. */
|
||||
export interface PublicReleaseNotes {
|
||||
projectName: string;
|
||||
projectKey: string;
|
||||
releaseName: string;
|
||||
description: string | null;
|
||||
status: string;
|
||||
targetDate: string | null;
|
||||
releasedAt: string | null;
|
||||
/** Markdown. */
|
||||
notes: string;
|
||||
/** False: drawn from its finished tickets (none written yet). */
|
||||
written: boolean;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import { Home } from '../models/home';
|
||||
import { PortfolioProject, ProjectInsights } from '../models/insights';
|
||||
import {
|
||||
DashboardShare,
|
||||
PublicReleaseNotes,
|
||||
ReleaseNotesShare,
|
||||
SharedBlock,
|
||||
SharedDashboard,
|
||||
} from '../models/sharing';
|
||||
@@ -474,6 +476,20 @@ export abstract class SharingGateway {
|
||||
abstract remove(projectId: string): Observable<void>;
|
||||
/** What a link shows, for anyone (null: no such link). */
|
||||
abstract shared(token: string): Observable<SharedDashboard | null>;
|
||||
/** A release's public notes link, if any (owners and admins). */
|
||||
abstract releaseNotesShare(
|
||||
releaseId: string,
|
||||
): Observable<ReleaseNotesShare | null>;
|
||||
/** Turns it on; `renew` makes a new link. */
|
||||
abstract shareReleaseNotes(
|
||||
releaseId: string,
|
||||
renew: boolean,
|
||||
): Observable<ReleaseNotesShare>;
|
||||
abstract unshareReleaseNotes(releaseId: string): Observable<void>;
|
||||
/** A release's notes for anyone with the link (null: no such link). */
|
||||
abstract publicReleaseNotes(
|
||||
token: string,
|
||||
): Observable<PublicReleaseNotes | null>;
|
||||
}
|
||||
|
||||
export abstract class NotificationsGateway {
|
||||
|
||||
Reference in New Issue
Block a user