Files

104 lines
4.0 KiB
Markdown
Raw Permalink Normal View History

# Aurora Moments
> Aurora Moments is not a social network that stores your pictures. It's your
> photo library with a social network built around it.
A self-hostable photo/video platform: a private, full-resolution photo
library (like iCloud Photos) with an explicit, opt-in social layer
("Moments") built on top of it. Uploading never equals publishing — a photo
only enters the social graph when its owner chooses to share it as a Moment.
## Architecture
```
docker-compose
│
├── postgres PostgreSQL — primary datastore
├── redis Celery broker/result backend
├── api Django + Django REST Framework
├── worker Celery worker (thumbnail/feed/large renditions, EXIF)
└── web React + TypeScript (Vite), talks to the API over REST
```
- **api/** — Django project. Apps: `accounts` (users, follows),
`library` (private originals, renditions, albums), `moments` (the social
posts, comments, reactions). JWT auth via `djangorestframework-simplejwt`.
- **web/** — React + TypeScript SPA (Vite). Login/Register, a private
Library grid with upload, and a Home feed of Moments.
- **mobile/** — not started; see [mobile/README.md](mobile/README.md).
### Storage
Original uploads and derived renditions (thumbnail/feed/large) go through
`MEDIA_BACKEND` in `.env`:
- `filesystem` (default) — written to `MEDIA_ROOT`, which you can bind-mount
to a NAS path in a self-hosted deployment.
- `s3` — any S3-compatible object store (AWS S3, MinIO, Backblaze B2, ...)
via `django-storages`, no code changes needed.
### Privacy model
- Everything uploaded to a user's Library is private by default.
- A **Moment** is one or more Library items + caption/location, shared with
an explicit `audience`: `public`, `followers`, `friends`, `family`,
`custom`, or `only_me`.
- `family` and `custom` currently fall back to owner-only visibility — full
circle/custom-audience membership is a V1.5 feature (see
`apps.moments.models.MomentQuerySet.visible_to`); shipping that stub now
was a deliberate choice to never over-share by default.
- Shared Albums (`apps.library.models.Album` + `AlbumCollaborator`) let
multiple people contribute full-resolution photos to one place (e.g. a
wedding), without the audience/feed logic of Moments.
## Running locally
```bash
cp .env.example .env
docker compose up --build
```
- Web: http://localhost:5173
- API: http://localhost:8000/api/
- Django admin: http://localhost:8000/admin/ (create a superuser first, see below)
Create a superuser for the Django admin:
```bash
docker compose exec api python manage.py createsuperuser
```
Migrations run automatically on `api` container start.
## What's in V1
- Registration/login (JWT), profiles, follow/followers
- Private full-resolution photo/video upload with async thumbnail/feed/large
rendition generation and EXIF extraction (Celery + Pillow)
- Share a Moment from existing Library items, with audience controls
- Home feed, comments, reactions (likes)
- Shared Albums with per-user roles (viewer/contributor/admin)
- Original-quality downloads (the original file is never deleted or resized
in place)
Deliberately **not** in V1 (see the original concept notes this repo is
based on): automatic iOS backup, push notifications, messaging, Memories,
maps, facial recognition, semantic AI search, Stories, video transcoding,
and server federation. Those come in V1.5/V2 once the core loop — private
library, explicit sharing — is proven.
## Backend layout
```
api/
├── config/ settings, urls, celery app
└── apps/
├── core/ shared abstract models (TimeStampedModel, Audience enum)
├── accounts/ User, Follow
├── library/ LibraryItem, MediaRendition, Album, AlbumItem, AlbumCollaborator
└── moments/ Moment, MomentItem, Comment, Reaction
```
REST API root: `/api/accounts/`, `/api/library/`, `/api/moments/`,
`/api/auth/token/` (JWT obtain/refresh).