docs: anleitung, changelog 0.3.0 und roadmap zu phase 3
Vier neue Kapitel in der Anleitung (mehrere Sammler, Preise, Erinnerungen, Dubletten) mit vier automatisch erzeugten Bildern, Changelog 0.3.0 samt der bewusst weggelassenen BrickLink-Anbindung, Roadmap abgehakt und um einen offenen Ausblick ergaenzt, Devlog mit Zeiten und Stolpersteinen. Dazu zwei Korrekturen aus dem Testlauf: Der Zeitplan fuer Erinnerungen liess sich nicht aus Next' instrumentation.ts starten - die Datei wird auch fuer die Edge-Runtime uebersetzt, und das native SQLite-Modul bricht dort den Build. Er startet jetzt aus dem Healthcheck heraus, den der Container ohnehin alle 30 Sekunden aufruft, und zusaetzlich aus dem App-Layout; der Aufruf ist idempotent. Der Screenshot-Lauf waehlte ploetzlich die falschen Kacheln aus: Der neue Sammler-Umschalter benutzt ebenfalls aria-pressed. Die Auswahlkacheln tragen jetzt ein eigenes data-set-card. Ausserdem raeumen die Testskripte einen Container weg, den ein abgebrochener Lauf zurueckgelassen hat - sonst blockiert er den Port. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
import { AppHeader } from '@/components/layout/app-header';
|
||||
import { BottomNav } from '@/components/layout/bottom-nav';
|
||||
import { ensureReminderScheduler } from '@/lib/reminder-job';
|
||||
import { requireUser } from '@/lib/session';
|
||||
|
||||
export default async function AppLayout({ children }: { children: React.ReactNode }) {
|
||||
// Second entry point besides the healthcheck, in case someone turns that
|
||||
// off. The call is idempotent.
|
||||
ensureReminderScheduler();
|
||||
|
||||
const user = await requireUser();
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { db } from '@/db';
|
||||
import { ensureReminderScheduler } from '@/lib/reminder-job';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
@@ -9,6 +10,10 @@ export const dynamic = 'force-dynamic';
|
||||
* file is readable - a healthy Node process on a broken volume is not healthy.
|
||||
*/
|
||||
export function GET() {
|
||||
// The container polls this every 30s, which makes it the earliest reliable
|
||||
// moment to have the reminder scheduler running. Repeat calls are free.
|
||||
ensureReminderScheduler();
|
||||
|
||||
try {
|
||||
db.get(sql`select 1`);
|
||||
return NextResponse.json({ status: 'ok', time: new Date().toISOString() });
|
||||
|
||||
@@ -208,6 +208,7 @@ export function CatalogGrid({
|
||||
<button
|
||||
key={item.id}
|
||||
type="button"
|
||||
data-set-card
|
||||
disabled={owned}
|
||||
aria-pressed={isSelected}
|
||||
onClick={() => toggle(item.id)}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* Runs once when the server starts.
|
||||
*
|
||||
* Next calls this before handling the first request, which is the one place a
|
||||
* long-lived background task can be started from.
|
||||
*/
|
||||
export async function register() {
|
||||
// Only in the Node runtime - the edge runtime has no timers that survive,
|
||||
// and the dev server would start a second scheduler on every reload.
|
||||
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
||||
if (process.env.NODE_ENV !== 'production') return;
|
||||
|
||||
const { startReminderScheduler } = await import('@/lib/reminder-job');
|
||||
startReminderScheduler();
|
||||
}
|
||||
@@ -107,6 +107,21 @@ export async function runReminderJob(now = new Date()): Promise<ReminderRun> {
|
||||
|
||||
const HOUR_MS = 60 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Started lazily from the first server render or healthcheck rather than from
|
||||
* Next's instrumentation hook: that hook is compiled for the edge runtime too,
|
||||
* and pulling the native SQLite driver into that bundle breaks the build.
|
||||
* Cached on globalThis so the dev server's module reloading cannot stack up
|
||||
* several schedulers.
|
||||
*/
|
||||
const globalForScheduler = globalThis as unknown as { bricktrackReminders?: boolean };
|
||||
|
||||
export function ensureReminderScheduler(): void {
|
||||
if (globalForScheduler.bricktrackReminders) return;
|
||||
globalForScheduler.bricktrackReminders = true;
|
||||
startReminderScheduler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the hourly check.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user