bootstrap rust services, auth, and compose stack

This commit is contained in:
2026-03-05 14:51:02 +01:00
parent 1238079454
commit 88db9805b5
25 changed files with 3576 additions and 22 deletions

89
infra/docker-compose.yml Normal file
View File

@@ -0,0 +1,89 @@
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: stripstream
POSTGRES_USER: stripstream
POSTGRES_PASSWORD: stripstream
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U stripstream -d stripstream"]
interval: 10s
timeout: 5s
retries: 5
meilisearch:
image: getmeili/meilisearch:v1.12
environment:
MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:-change-me}
ports:
- "7700:7700"
volumes:
- meili_data:/meili_data
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:7700/health"]
interval: 10s
timeout: 5s
retries: 5
api:
build:
context: ..
dockerfile: apps/api/Dockerfile
env_file:
- ../.env
ports:
- "8080:8080"
depends_on:
postgres:
condition: service_healthy
meilisearch:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:8080/health"]
interval: 10s
timeout: 5s
retries: 5
indexer:
build:
context: ..
dockerfile: apps/indexer/Dockerfile
env_file:
- ../.env
ports:
- "8081:8081"
depends_on:
postgres:
condition: service_healthy
meilisearch:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:8081/health"]
interval: 10s
timeout: 5s
retries: 5
admin-ui:
build:
context: ..
dockerfile: apps/admin-ui/Dockerfile
env_file:
- ../.env
ports:
- "8082:8082"
depends_on:
api:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:8082/health"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:
meili_data:

View File

@@ -0,0 +1,67 @@
CREATE TABLE IF NOT EXISTS libraries (
id UUID PRIMARY KEY,
name TEXT NOT NULL,
root_path TEXT NOT NULL UNIQUE,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS books (
id UUID PRIMARY KEY,
library_id UUID NOT NULL REFERENCES libraries(id) ON DELETE CASCADE,
kind TEXT NOT NULL CHECK (kind IN ('ebook', 'comic', 'bd')),
title TEXT NOT NULL,
author TEXT,
series TEXT,
volume TEXT,
language TEXT,
page_count INT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS book_files (
id UUID PRIMARY KEY,
book_id UUID NOT NULL REFERENCES books(id) ON DELETE CASCADE,
format TEXT NOT NULL CHECK (format IN ('pdf', 'cbz', 'cbr')),
abs_path TEXT NOT NULL UNIQUE,
size_bytes BIGINT NOT NULL,
mtime TIMESTAMPTZ NOT NULL,
fingerprint TEXT NOT NULL,
checksum_opt TEXT,
parse_status TEXT NOT NULL DEFAULT 'pending' CHECK (parse_status IN ('pending', 'ok', 'error')),
parse_error_opt TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS index_jobs (
id UUID PRIMARY KEY,
library_id UUID REFERENCES libraries(id) ON DELETE SET NULL,
type TEXT NOT NULL CHECK (type IN ('scan', 'rebuild')),
status TEXT NOT NULL CHECK (status IN ('pending', 'running', 'success', 'failed')),
started_at TIMESTAMPTZ,
finished_at TIMESTAMPTZ,
stats_json JSONB,
error_opt TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS api_tokens (
id UUID PRIMARY KEY,
name TEXT NOT NULL,
prefix TEXT NOT NULL UNIQUE,
token_hash TEXT NOT NULL,
scope TEXT NOT NULL CHECK (scope IN ('admin', 'read')),
last_used_at TIMESTAMPTZ,
revoked_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_books_library_id ON books(library_id);
CREATE INDEX IF NOT EXISTS idx_book_files_book_id ON book_files(book_id);
CREATE INDEX IF NOT EXISTS idx_book_files_parse_status ON book_files(parse_status);
CREATE INDEX IF NOT EXISTS idx_index_jobs_status ON index_jobs(status);
CREATE INDEX IF NOT EXISTS idx_api_tokens_scope ON api_tokens(scope);