chore: beta release v0.5.0-beta
- Bump version to 0.5.0-beta - Add Apache-2.0 LICENSE (official text) + NOTICE - Add Docker support: multi-stage Dockerfile + docker-compose * non-root user, tini PID 1, gunicorn + uvicorn workers * healthcheck, OCI labels, persistent /data volume - Add GitHub Actions CI (lint/import-check + Docker smoke-test) - Backend polish: * modern lifespan handler (replaces deprecated on_event) * explicit sort validation (400 instead of 500) * title min_length=1 schema validation * configurable data dir + http timeout via env * avg_rating helper extracted (DRY) - Frontend polish: * beta badge in title, footer with live version * loading spinner on initial fetch * updated README, badges, config table, roadmap
This commit is contained in:
+6
-6
@@ -4,6 +4,7 @@ Zentrale Idee: ein polymorphes ``Media``-Objekt mit ``kind`` (book/series), das
|
||||
optionale, mediumspezifische Felder als NULL-sparende Spalten mitführt. So
|
||||
müssen wir keine separaten Tabellen für Bücher vs. Serien pflegen.
|
||||
"""
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date, datetime, timezone
|
||||
@@ -21,7 +22,6 @@ from sqlalchemy import (
|
||||
String,
|
||||
Table,
|
||||
Text,
|
||||
UniqueConstraint,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
@@ -66,7 +66,7 @@ class Tag(Base):
|
||||
|
||||
# ---------- Hauptentität: Media ----------------------------------------------
|
||||
|
||||
# Status-Werte (an MAL angelehnt, aber für Bücher + Serien nutzbar):
|
||||
# Status (an MAL angelehnt, für Bücher + Serien nutzbar):
|
||||
# plan -> auf der Liste / will ich lesen/schauen
|
||||
# reading -> lese ich gerade (Buch) ODER watching (Serie)
|
||||
# done -> fertig (abgeschlossen)
|
||||
@@ -84,7 +84,7 @@ class Media(Base):
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
|
||||
# Allgemein
|
||||
kind: Mapped[str] = mapped_column(String(16), nullable=False) # book|series
|
||||
kind: Mapped[str] = mapped_column(String(16), nullable=False)
|
||||
title: Mapped[str] = mapped_column(String(200), nullable=False)
|
||||
original_title: Mapped[Optional[str]] = mapped_column(String(200))
|
||||
description: Mapped[Optional[str]] = mapped_column(Text)
|
||||
@@ -97,15 +97,15 @@ class Media(Base):
|
||||
# Buch-spezifisch
|
||||
author: Mapped[Optional[str]] = mapped_column(String(200))
|
||||
isbn: Mapped[Optional[str]] = mapped_column(String(20))
|
||||
total_volumes: Mapped[Optional[int]] = mapped_column(Integer) # Bände
|
||||
total_chapters: Mapped[Optional[int]] = mapped_column(Integer) # Kapitel
|
||||
total_volumes: Mapped[Optional[int]] = mapped_column(Integer)
|
||||
total_chapters: Mapped[Optional[int]] = mapped_column(Integer)
|
||||
total_pages: Mapped[Optional[int]] = mapped_column(Integer)
|
||||
volumes_read: Mapped[Optional[int]] = mapped_column(Integer, default=0)
|
||||
chapters_read: Mapped[Optional[int]] = mapped_column(Integer, default=0)
|
||||
pages_read: Mapped[Optional[int]] = mapped_column(Integer, default=0)
|
||||
|
||||
# Serien-spezifisch
|
||||
network: Mapped[Optional[str]] = mapped_column(String(120)) # Sender/Streaming
|
||||
network: Mapped[Optional[str]] = mapped_column(String(120))
|
||||
total_seasons: Mapped[Optional[int]] = mapped_column(Integer)
|
||||
total_episodes: Mapped[Optional[int]] = mapped_column(Integer)
|
||||
episodes_watched: Mapped[Optional[int]] = mapped_column(Integer, default=0)
|
||||
|
||||
Reference in New Issue
Block a user