Mycelium

Mycelium — Family History Tracker

Build your family tree, save stories, and explore where your family came from on a 3D globe.

Backend setup (Django)

Prerequisites:

  1. Create and activate the virtual environment (already present as backend/venv; to recreate: python -m venv backend\venv):

    backend\venv\Scripts\Activate.ps1
    

    If PowerShell blocks activation scripts, do not weaken the global execution policy. Instead call the venv Python directly, e.g. backend\venv\Scripts\python.exe -m pip ....

  2. Install dependencies:

    backend\venv\Scripts\python.exe -m pip install -r backend\requirements.txt
    
  3. Create the local environment file (already present as backend/.env; to recreate: copy backend/.env.example to backend/.env). backend/.env is git-ignored — never commit it. No database credentials are needed for the default SQLite setup.

  4. Run Django checks:

    backend\venv\Scripts\python.exe backend\manage.py check
    
  5. Apply migrations (creates backend/db.sqlite3 on first run):

    backend\venv\Scripts\python.exe backend\manage.py migrate
    
  6. Start the development server:

    backend\venv\Scripts\python.exe backend\manage.py runserver
    
  7. Health check: GET http://127.0.0.1:8000/api/health/ should return {"status": "ok", "service": "mycelium-backend", "version": "0.1.0"}. It needs no database and exposes no configuration or secrets.

Run the backend tests (87 tests, real project settings) with:

backend\venv\Scripts\python.exe backend\manage.py test

Production: PostgreSQL on Render (not local dev)

SQLite is the default and is all local development needs. For production:

  1. Create a PostgreSQL database on Render and copy its credentials.
  2. In the Render dashboard (never in Git), set DB_ENGINE=postgresql plus POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, along with DJANGO_SECRET_KEY, DJANGO_DEBUG=False, DJANGO_ALLOWED_HOSTS (your domain), FRONTEND_ORIGIN (your frontend URL), and DJANGO_SECURE=1.
  3. Deploy, then run migrations once (python manage.py migrate).
  4. Media: set CLOUDINARY_URL so uploads persist; email: set the EMAIL_* values for Gmail SMTP delivery.

PostgreSQL compatibility has only been statically checked here (sqlmigrate rendering); no live PostgreSQL server was available, so a live integration test is still required before relying on it.

Render deployment checklist

  1. In Render, choose New > Blueprint, connect this repository, and deploy the root render.yaml. It creates a free backend Web Service and a separate paid PostgreSQL database, generates DJANGO_SECRET_KEY, and wires the database credentials and allowed host automatically. Review Render’s current database price before approving. The frontend and API share the backend origin. The start command applies database migrations before launching the backend.
  2. For durable photo uploads, add CLOUDINARY_URL in the Render dashboard. Without it, uploads use the web service’s ephemeral filesystem and can disappear after a restart or redeploy.
  3. Add GROQ_API_KEY there to enable the AI story helper; configure EMAIL_* only if real email delivery is needed.
  4. Configure Render PostgreSQL backups and take a manual snapshot before important migrations.
  5. Smoke test after deploy: HTTPS, login/logout, member create, photo download, health endpoint.

Groq API key (AI story helper)

  1. Create a free account at https://console.groq.com, open API Keys, and create a key. It stays server-side: set GROQ_API_KEY in the Render dashboard (locally: backend/.env, never committed).
  2. The default model is openai/gpt-oss-20b (a currently supported Groq model; override with GROQ_MODEL if Groq retires it). The helper is rate-limited to 20 requests/hour per account.
  3. Without a key the endpoint honestly answers 503 and the UI explains the helper is unconfigured — everything else keeps working.

Gmail App Passwords (for password reset delivery)

  1. Enable 2-Step Verification on the Gmail account, then create an App Password (Google Account → Security → App passwords).
  2. Set DJANGO_EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend, EMAIL_HOST=smtp.gmail.com, EMAIL_PORT=587, EMAIL_HOST_USER=<address>, EMAIL_HOST_PASSWORD=<16-char app password>, DEFAULT_FROM_EMAIL=Mycelium <<address>> in the Render dashboard.
  3. Real delivery is unverified here; send a reset email after deploy and confirm receipt before announcing the feature.

Existing local media on deploy

backend/media/ is git-ignored and stays on this machine — it is not deployed. After launch, either re-upload photos (they land in Cloudinary once CLOUDINARY_URL is set) or copy the files into Cloudinary manually. Do not make the local media directory public.

Backend implementation status

Done (foundation + family API):

Done (accounts and private trees):

Frontend integration (all live, verified against the API):

Known setup limitations