Keep e621 metadata on downloaded posts; clear up account roles

Roles:
- JakeBreathild is now staff + superuser (the real account); the 'jake'
  smoke-test account was demoted to a regular user
- /me exposes is_superuser and the account page shows an admin badge

e621 metadata:
- MediaItem gains e621_post_id and e621_data (trimmed post payload:
  tags by category, rating, score, favourites, comments, sources,
  description, pools, relationships, file info, uploader)
- Download to Library accepts the post payload from the SPA and stores
  it; the item's custom rating is seeded from the e621 rating when empty
- Library detail shows an e621 metadata card: link to the in-app post,
  score/favourites/comments, taxonomy-coloured tags, DText description,
  sources and pools; grid cards get an e621 badge and fall back to the
  e621 rating for their colour (display_rating)
- Guest visibility now also considers e621 tags, so downloaded explicit
  content is hidden from anonymous visitors
This commit is contained in:
2026-09-17 10:27:06 -05:00
parent e5cc63b0cc
commit ebac3ac922
13 changed files with 343 additions and 29 deletions
+33
View File
@@ -3,6 +3,7 @@ export interface User {
username: string;
email: string;
is_staff: boolean;
is_superuser: boolean;
date_joined: string;
role: "user" | "uploader" | "staff";
can_upload: boolean;
@@ -19,12 +20,42 @@ export interface MediaLocation {
export type Rating = "" | "s" | "q" | "e";
export interface E621StoredPost {
id: number | null;
created_at?: string | null;
rating?: "s" | "q" | "e" | null;
tags: Record<string, string[]>;
score?: {
up?: number | null;
down?: number | null;
total?: number | null;
} | null;
fav_count?: number | null;
comment_count?: number | null;
sources: string[];
description: string;
pools: number[];
relationships?: {
parent_id?: number | null;
has_children?: boolean | null;
} | null;
file?: {
md5?: string | null;
ext?: string | null;
size?: number | null;
width?: number | null;
height?: number | null;
} | null;
uploader_name?: string | null;
}
export interface MediaItem {
id: number;
j_id: string;
md5: string;
size: number;
rating: Rating;
display_rating: Rating;
tags: string[];
notes: string;
filename: string;
@@ -32,6 +63,8 @@ export interface MediaItem {
kind: "image" | "video";
uploaded_by: string | null;
uploaded_by_id: number | null;
e621_post_id: number | null;
e621_data: E621StoredPost | null;
locations: MediaLocation[];
created_at: string;
updated_at: string;