feat(aether): initial commit – self-hosted Cloud, Phasen 1–7

Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA.
Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb,
Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming,
Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office
(Collabora/OnlyOffice).

Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort)
sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 5 committed 2026-08-24 09:25:36 +02:00
commit 31a027c93a
225 files changed
+38042

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
package files
import (
"time"
"github.com/google/uuid"
)
type File struct {
ID uuid.UUID `json:"id"`
// Entweder OwnerID oder GroupID ist gesetzt, nie beides: Eine Datei gehört
// einem Konto oder einer Gruppe. Die Datenbank erzwingt das per CHECK.
OwnerID *uuid.UUID `json:"owner_id"`
GroupID *uuid.UUID `json:"group_id"`
FolderID *uuid.UUID `json:"folder_id"`
Name string `json:"name"`
MimeType string `json:"mime_type"`
Size int64 `json:"size"`
Checksum string `json:"checksum"`
StorageKey string `json:"-"`
HasThumbnail bool `json:"has_thumbnail"`
Version int `json:"version"`
// VersioningEnabled ist Opt-in: nur dann hebt eine Überschreibung die
// vorige Fassung auf. Sonst wird sie ersetzt und der Platz freigegeben.
VersioningEnabled bool `json:"versioning_enabled"`
// DocumentDate ist das Datum, das auf dem Dokument steht – Kaufdatum,
// Rechnungsdatum. Nicht zu verwechseln mit CreatedAt (dem Upload): Ein
// Beleg von Dezember, im Januar eingescannt, gehört ins alte Jahr.
// NULL heißt „nicht gesetzt"; bei einem Urlaubsfoto gibt es keins.
DocumentDate *time.Time `json:"document_date,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type FileVersion struct {
ID uuid.UUID `json:"id"`
FileID uuid.UUID `json:"file_id"`
Version int `json:"version"`
Size int64 `json:"size"`
Checksum string `json:"checksum"`
StorageKey string `json:"-"`
CreatedAt time.Time `json:"created_at"`
}
type Folder struct {
ID uuid.UUID `json:"id"`
// Siehe File: entweder Konto oder Gruppe.
OwnerID *uuid.UUID `json:"owner_id"`
GroupID *uuid.UUID `json:"group_id"`
ParentID *uuid.UUID `json:"parent_id"`
Name string `json:"name"`
CreatedAt time.Time `json:"created_at"`
}
type Favorite struct {
ID uuid.UUID `json:"id"`
UserID uuid.UUID `json:"user_id"`
FolderID uuid.UUID `json:"folder_id"`
Position int `json:"position"`
IsExpanded bool `json:"is_expanded"`
CreatedAt time.Time `json:"created_at"`
FolderName string `json:"folder_name"`
FolderParentID *uuid.UUID `json:"folder_parent_id"`
}