Add public feed, admin area, self-registration, visibility & hashtags
Some checks failed
Deploy to NAS / deploy (push) Failing after 26s

- Public feed (/) with infinite scroll via Intersection Observer
- Self-registration (/register)
- Admin area (/admin/entries, /admin/users) with user management
- journal_entries: visibility (public/private) + hashtags fields
- users: is_admin flag
- DB schema updated (recreate DB to apply)
- CI: run go test via docker run (golang:1.25-alpine) — fixes 'go not found'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christoph K.
2026-04-07 20:53:31 +02:00
parent 034d16e059
commit 86627f94b1
20 changed files with 783 additions and 92 deletions

View File

@@ -178,16 +178,17 @@ backend/
│ ├── trackpoints.go UpsertBatch, ListByDate, ListDays, EnsureDevice
│ ├── stops.go ListByDate
│ ├── suggestions.go ListByDate
── journal.go CRUD Journal Entries + Images
── journal.go CRUD Journal Entries + Images; ListPublic, ListByUser
│ └── users.go ListUsers, DeleteUser
├── auth/
│ └── auth.go HashPassword, VerifyPassword, Login, GetSession, Logout
│ └── auth.go HashPassword, VerifyPassword, Login, Register, GetSession, Logout
└── api/
├── router.go chi Routing, Middleware-Gruppen
├── middleware.go RequireAuth (Session Cookie → Context)
├── middleware.go RequireAuth, requireAdmin (Session Cookie → Context)
├── ingest.go HandleSingleTrackpoint, HandleBatchTrackpoints
├── query.go HandleListDays, HandleListTrackpoints, Stops, Suggestions
├── webui.go Server-side rendered Web UI (Go Templates)
├── journal.go Journal Entry Endpoints
├── webui.go Web UI: Feed, Register, Days, Admin-Handlers
├── journal.go Journal Entry Endpoints (inkl. visibility + hashtags)
└── response.go writeJSON, writeError helpers
```
@@ -365,6 +366,101 @@ Schema wird beim API-Start automatisch initialisiert (keine separate Migration n
---
## 7b. Datenbankschema
```mermaid
erDiagram
users {
TEXT user_id PK
TEXT username UK
TEXT password_hash
BOOLEAN is_admin
TIMESTAMPTZ created_at
}
sessions {
TEXT session_id PK
TEXT user_id FK
TIMESTAMPTZ created_at
TIMESTAMPTZ expires_at
}
devices {
TEXT device_id PK
TEXT user_id FK
TIMESTAMPTZ created_at
}
trackpoints {
BIGSERIAL id PK
TEXT event_id
TEXT device_id FK
TEXT trip_id
TIMESTAMPTZ ts
DOUBLE lat
DOUBLE lon
TEXT source
TEXT note
}
stops {
TEXT stop_id PK
TEXT device_id FK
TEXT trip_id
TIMESTAMPTZ start_ts
TIMESTAMPTZ end_ts
DOUBLE center_lat
DOUBLE center_lon
INT duration_s
TEXT place_label
}
suggestions {
TEXT suggestion_id PK
TEXT stop_id FK
TEXT type
TEXT title
TEXT text
TIMESTAMPTZ created_at
TIMESTAMPTZ dismissed_at
}
journal_entries {
TEXT entry_id PK
TEXT user_id FK
DATE entry_date
TIME entry_time
TEXT title
TEXT description
DOUBLE lat
DOUBLE lon
TEXT visibility
TEXT[] hashtags
TIMESTAMPTZ created_at
}
journal_images {
TEXT image_id PK
TEXT entry_id FK
TEXT filename
TEXT original_name
TEXT mime_type
BIGINT size_bytes
TIMESTAMPTZ created_at
}
users ||--o{ sessions : has
users ||--o{ devices : owns
users ||--o{ journal_entries : writes
devices ||--o{ trackpoints : records
stops ||--o{ suggestions : generates
journal_entries ||--o{ journal_images : contains
```
**Wichtige Felder:**
| Tabelle | Feld | Bedeutung |
|---------|------|-----------|
| `users` | `is_admin` | Admin-Flag für Zugang zum Admin-Bereich |
| `journal_entries` | `visibility` | `public` = im öffentlichen Feed sichtbar; `private` = nur für Autor |
| `journal_entries` | `hashtags` | Kommagetrennte Tags als `TEXT[]`-Array |
| `trackpoints` | `(device_id, event_id)` | UNIQUE-Constraint für Idempotenz |
---
## 8. Querschnittskonzepte
### Authentifizierung & Sessions (REQ-AUTH-01, REQ-AUTH-02, DEC-AUTH-01)