# 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).