Kyle Pope 3d22568b9c Add user connections, notification centre, and people integration
Implements the full User Connections & Notification Centre feature:

Phase 1 - Database: migrations 039-043 adding umbral_name to users,
profile/social fields to settings, notifications table, connection
request/user_connection tables, and linked_user_id to people.

Phase 2 - Notifications: backend CRUD router + service + 90-day purge,
frontend NotificationsPage with All/Unread filter, bell icon in sidebar
with unread badge polling every 60s.

Phase 3 - Settings: profile fields (phone, mobile, address, company,
job_title), social card with accept_connections toggle and per-field
sharing defaults, umbral name display with CopyableField.

Phase 4 - Connections: timing-safe user search, send/accept/reject flow
with atomic status updates, bidirectional UserConnection + Person records,
in-app + ntfy notifications, per-receiver pending cap, nginx rate limiting.

Phase 5 - People integration: batch-loaded shared profiles (N+1 prevention),
Ghost icon for umbral contacts, Umbral filter pill, split Add Person button,
shared field indicators (synced labels + Lock icons), disabled form inputs
for synced fields on umbral contacts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 02:10:16 +08:00
..
2026-02-15 16:13:41 +08:00
2026-02-15 16:13:41 +08:00
2026-02-15 16:13:41 +08:00

UMBRA Backend

A complete FastAPI backend for the UMBRA application with async SQLAlchemy, PostgreSQL, authentication, and comprehensive CRUD operations.

Features

  • FastAPI with async/await support
  • SQLAlchemy 2.0 with async engine
  • PostgreSQL with asyncpg driver
  • Alembic for database migrations
  • bcrypt for password hashing
  • itsdangerous for session management
  • PIN-based authentication with secure session cookies
  • Full CRUD operations for all entities
  • Dashboard with aggregated data
  • CORS enabled for frontend integration

Project Structure

backend/
├── alembic/                 # Database migrations
│   ├── versions/           # Migration files
│   ├── env.py             # Alembic environment
│   └── script.py.mako     # Migration template
├── app/
│   ├── models/            # SQLAlchemy models
│   ├── schemas/           # Pydantic schemas
│   ├── routers/           # API route handlers
│   ├── config.py          # Configuration
│   ├── database.py        # Database setup
│   └── main.py            # FastAPI application
├── requirements.txt       # Python dependencies
├── Dockerfile            # Docker configuration
├── alembic.ini          # Alembic configuration
└── start.sh             # Startup script

Setup

1. Install Dependencies

cd backend
pip install -r requirements.txt

2. Configure Environment

Create a .env file:

DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/umbra
SECRET_KEY=your-secret-key-change-in-production

3. Create Database

createdb umbra

4. Run Migrations

alembic upgrade head

5. Start Server

# Using the start script
chmod +x start.sh
./start.sh

# Or directly with uvicorn
uvicorn app.main:app --reload

The API will be available at http://localhost:8000

API Documentation

Interactive API documentation is available at:

API Endpoints

Authentication

  • POST /api/auth/setup - Initial PIN setup
  • POST /api/auth/login - Login with PIN
  • POST /api/auth/logout - Logout
  • GET /api/auth/status - Check auth status

Todos

  • GET /api/todos - List todos (with filters)
  • POST /api/todos - Create todo
  • GET /api/todos/{id} - Get todo
  • PUT /api/todos/{id} - Update todo
  • DELETE /api/todos/{id} - Delete todo
  • PATCH /api/todos/{id}/toggle - Toggle completion

Calendar Events

  • GET /api/events - List events (with date range)
  • POST /api/events - Create event
  • GET /api/events/{id} - Get event
  • PUT /api/events/{id} - Update event
  • DELETE /api/events/{id} - Delete event

Reminders

  • GET /api/reminders - List reminders (with filters)
  • POST /api/reminders - Create reminder
  • GET /api/reminders/{id} - Get reminder
  • PUT /api/reminders/{id} - Update reminder
  • DELETE /api/reminders/{id} - Delete reminder
  • PATCH /api/reminders/{id}/dismiss - Dismiss reminder

Projects

  • GET /api/projects - List projects
  • POST /api/projects - Create project
  • GET /api/projects/{id} - Get project
  • PUT /api/projects/{id} - Update project
  • DELETE /api/projects/{id} - Delete project
  • GET /api/projects/{id}/tasks - List project tasks
  • POST /api/projects/{id}/tasks - Create project task
  • PUT /api/projects/{id}/tasks/{task_id} - Update task
  • DELETE /api/projects/{id}/tasks/{task_id} - Delete task

People

  • GET /api/people - List people (with search)
  • POST /api/people - Create person
  • GET /api/people/{id} - Get person
  • PUT /api/people/{id} - Update person
  • DELETE /api/people/{id} - Delete person

Locations

  • GET /api/locations - List locations (with category filter)
  • POST /api/locations - Create location
  • GET /api/locations/{id} - Get location
  • PUT /api/locations/{id} - Update location
  • DELETE /api/locations/{id} - Delete location

Settings

  • GET /api/settings - Get settings
  • PUT /api/settings - Update settings
  • PUT /api/settings/pin - Change PIN

Dashboard

  • GET /api/dashboard - Get dashboard data
  • GET /api/upcoming?days=7 - Get upcoming items

Database Schema

The application uses the following tables:

  • settings - Application settings and PIN
  • todos - Task items
  • calendar_events - Calendar events
  • reminders - Reminders
  • projects - Projects
  • project_tasks - Tasks within projects
  • people - Contacts/people
  • locations - Physical locations

Docker

Build and run with Docker:

docker build -t umbra-backend .
docker run -p 8000:8000 -e DATABASE_URL=... -e SECRET_KEY=... umbra-backend

Development

Create New Migration

alembic revision --autogenerate -m "Description of changes"

Apply Migrations

alembic upgrade head

Rollback Migration

alembic downgrade -1

Security Notes

  • Change SECRET_KEY in production
  • Use strong PINs (minimum 4 digits recommended)
  • Session cookies are httpOnly and last 30 days
  • All API endpoints (except auth) require authentication
  • PINs are hashed with bcrypt before storage