v3: comments say what the code can't — the documentation pass wanted JSDoc on every export and every field of an exported interface, which filled the code with restatements ("The dump.", "Whether it is loading.", "The props of X.", "Renders the X.") and module docs that told a reader nothing ("The hot and new feeds, and the props every main feed of the index takes."); some were wrong as well as vague. Every comment in api/, shared/ and src/ is rewritten under one rule, now stated in the README's "Comments" section: every module and export still has a JSDoc, and it gives context (who uses it and where), usage (what a caller must know: a precondition, what it leaves to the caller, a side effect) or its place in the chain (where its input comes from, where its output goes); a field, parameter, private function or local gets one only when it adds to its parent's, and context about a whole type goes on the type; a type's doc is phrased from the value's side ("Returned to Y by X when Z", "Passed to Y by X"); full sentences, as short as they can be, no label-colon-list; // goes wherever the code isn't obvious and says why, and the section banners and narration go. Every claim was checked against the code, which turned up some forty comments that were wrong: DumpCard's claimed it was only used by the hot and new feeds, the WebSocket welcome claimed to be a socket's first message (presence comes first), UpdateUserRequest said null removes a description (it keeps it), deletedDumpIds leaves out that it also holds dumps made private, THEME_COLOR claimed to mirror index.html's, and the like. The routers' JSDoc now says where they are mounted and what becomes of a thrown APIException. doc-lint.ts lets a field without a doc through; a module or export without one still fails. No code changes; 204 backend and 628 frontend tests pass, and doc:lint, deno check, deno lint and tsc are clean.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,80 +1,91 @@
|
||||
/**
|
||||
* Playlists — ordered collections of dumps — and the bodies that create, edit
|
||||
* and reorder them.
|
||||
* Declares playlists, the ordered collections of dumps their owners curate, and
|
||||
* the bodies that create, edit and reorder them. The client shows them on
|
||||
* `/playlists/:playlistId`, on profiles and in search results.
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
import type { Dump } from "./dump.ts";
|
||||
|
||||
/** A playlist. */
|
||||
/**
|
||||
* Returned by the playlist routes, and by the search, users and dumps routes
|
||||
* that list playlists. The `playlist_created` and `playlist_updated` WebSocket
|
||||
* messages carry it too.
|
||||
*/
|
||||
export interface Playlist {
|
||||
/** The playlist's id. */
|
||||
id: string;
|
||||
/** The owner's id. */
|
||||
userId: string;
|
||||
/** The playlist's title. */
|
||||
title: string;
|
||||
/** The playlist's URL slug. */
|
||||
slug?: string;
|
||||
/** The owner's description, in Markdown. */
|
||||
/** It is written in Markdown. */
|
||||
description?: string;
|
||||
/** Whether anyone may see it, or only its owner. */
|
||||
/**
|
||||
* Only its owner sees a private playlist. Moderators don't, though they may
|
||||
* still edit or delete it.
|
||||
*/
|
||||
isPublic: boolean;
|
||||
/** When the playlist was created. */
|
||||
createdAt: Date;
|
||||
/** When the playlist was last changed, if ever. */
|
||||
/**
|
||||
* `playlistImageUrl` puts it on the cover's URL, so a new cover isn't hidden
|
||||
* by the cached old one.
|
||||
*/
|
||||
updatedAt?: Date;
|
||||
/** The cover image's type, undefined without one. */
|
||||
/** It is undefined when the playlist has no cover. */
|
||||
imageMime?: string;
|
||||
/**
|
||||
* How many dumps it holds, private ones included, where the query counts
|
||||
* them.
|
||||
* It counts the dumps the viewer can't see too. It is undefined when the
|
||||
* query didn't count them, as for a new playlist or a membership.
|
||||
*/
|
||||
dumpCount?: number;
|
||||
/** The owner's name, where the query joins it. */
|
||||
/** It is undefined where `dumpCount` is. */
|
||||
ownerUsername?: string;
|
||||
}
|
||||
|
||||
/** A playlist with the dumps the caller may see in it, in order. */
|
||||
/**
|
||||
* Returned by `GET /api/playlists/:playlistId` to `PlaylistDetail`, with the
|
||||
* dumps the caller may see, in the playlist's order.
|
||||
*/
|
||||
export interface PlaylistWithDumps extends Playlist {
|
||||
/** The dumps, in the playlist's order. */
|
||||
dumps: Dump[];
|
||||
}
|
||||
|
||||
/**
|
||||
* `GET /api/playlists/by-dump/:dumpId/memberships`: one of the caller's
|
||||
* playlists, and whether it holds the dump.
|
||||
* Returned by `GET /api/playlists/by-dump/:dumpId/memberships`, one per
|
||||
* playlist of the caller's. `PlaylistMembershipPanel` ticks the playlists
|
||||
* with `hasDump`, in the add-to-playlist modal and the dump form.
|
||||
*/
|
||||
export interface PlaylistMembership {
|
||||
/** The playlist. */
|
||||
playlist: Playlist;
|
||||
/** Whether it holds the dump. */
|
||||
hasDump: boolean;
|
||||
}
|
||||
|
||||
/** The body of `POST /api/playlists`. */
|
||||
/** Passed to `POST /api/playlists` by `PlaylistCreateForm`. */
|
||||
export interface CreatePlaylistRequest {
|
||||
/** The new playlist's title. */
|
||||
title: string;
|
||||
/** Its description, in Markdown. */
|
||||
description?: string;
|
||||
/** Whether anyone may see it. */
|
||||
isPublic: boolean;
|
||||
}
|
||||
|
||||
/** The body of `PUT /api/playlists/:playlistId`: the fields to change. */
|
||||
/**
|
||||
* Passed to `PUT /api/playlists/:playlistId` by `PlaylistDetail`. A field left
|
||||
* out keeps its value.
|
||||
*/
|
||||
export interface UpdatePlaylistRequest {
|
||||
/** The new title. */
|
||||
title?: string;
|
||||
/** The new description; `null` removes it. */
|
||||
/** `null` removes the description. */
|
||||
description?: string | null;
|
||||
/** Whether anyone may see it. */
|
||||
isPublic?: boolean;
|
||||
}
|
||||
|
||||
/** The body of `PUT /api/playlists/:playlistId/order`. */
|
||||
/**
|
||||
* Passed to `PUT /api/playlists/:playlistId/order` by `PlaylistDetail`, after
|
||||
* a drag or to put back a dump whose removal was undone.
|
||||
*/
|
||||
export interface ReorderPlaylistRequest {
|
||||
/** Every dump of the playlist the caller can see, in the new order. */
|
||||
/**
|
||||
* Every dump of the playlist the caller can see, in the new order. The dumps
|
||||
* hidden from them keep their slots.
|
||||
*/
|
||||
dumpIds: string[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user