# BirdWatch Survey

BirdWatch Survey is an open-source citizen-science project for recording bird sightings and producing consistent, research-ready observations. Volunteers can submit surveys from local parks, backyards, wetlands, and other habitats while project coordinators review records and export data for conservation and ecological research.

## Features

- Record species, counts, date, time, location, and survey duration
- Capture habitat, weather, distance, and observation notes
- Support complete checklists and incidental sightings
- Flag unusual species or high counts for expert review
- Import observations from CSV files
- Export validated records as CSV or GeoJSON
- Protect sensitive species by obscuring public coordinates
- Run locally with SQLite or in production with PostgreSQL
- Provide a responsive interface for phones, tablets, and desktops

## Requirements

- Python 3.11 or later
- Node.js 20 or later
- npm 10 or later
- PostgreSQL 15 or later for production deployments

SQLite is used by default for local development.

## Installation

Clone the repository and enter the project directory:

```bash
git clone https://github.com/example/birdwatch-survey.git
cd birdwatch-survey
```

Create a Python virtual environment and install the server dependencies:

```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

On Windows PowerShell, activate the environment with:

```powershell
.venv\Scripts\Activate.ps1
```

Install the web application dependencies:

```bash
npm install
```

Create a local configuration file and initialize the database:

```bash
cp .env.example .env
python manage.py migrate
python manage.py seed_species
```

Start the development services:

```bash
python manage.py runserver
npm run dev
```

Open `http://localhost:8000` in a browser.

## Usage

### Submit a survey

1. Create an account or sign in.
2. Select **New Survey**.
3. Choose a location on the map or enter coordinates.
4. Add the survey start time, duration, distance traveled, habitat, and weather.
5. Record every species detected and the number of individuals observed.
6. Mark the checklist as complete if all detected species were reported.
7. Review the entries and submit the survey.

Use an incidental sighting for observations made outside a structured survey. Incidental records are useful, but they should not be marked as complete checklists.

### Review observations

Users with the `reviewer` role can open the review queue to inspect records flagged because of rarity, season, location, or count. Reviewers can approve a record, request additional evidence, correct taxonomy, or reject an unverifiable observation.

Photographs and audio recordings may support an observation but should not include private information or disturb birds during collection.

### Import data

Prepare a UTF-8 CSV file containing the required columns:

```text
observed_at,latitude,longitude,species_code,count
2026-05-12T07:30:00-04:00,43.6532,-79.3832,amerob,3
```

Import and validate it before committing records:

```bash
python manage.py import_surveys observations.csv --dry-run
python manage.py import_surveys observations.csv
```

### Export data

Export approved observations for a date range:

```bash
python manage.py export_observations \
  --from 2026-05-01 \
  --to 2026-05-31 \
  --format csv \
  --output may-observations.csv
```

Supported formats are `csv` and `geojson`. Public exports automatically obscure coordinates for species configured as sensitive.

## Configuration

Configuration is read from environment variables or a local `.env` file.

| Variable | Default | Description |
| --- | --- | --- |
| `APP_ENV` | `development` | Runtime environment: `development`, `test`, or `production` |
| `SECRET_KEY` | — | Secret used for sessions and signed tokens |
| `DATABASE_URL` | `sqlite:///birdwatch.db` | Database connection URL |
| `PUBLIC_BASE_URL` | `http://localhost:8000` | Public URL of the application |
| `DEFAULT_TIMEZONE` | `UTC` | Time zone used when an observation has no offset |
| `DEFAULT_REGION` | — | Optional region code used for species suggestions |
| `REQUIRE_EMAIL_VERIFICATION` | `false` | Require verification before users submit surveys |
| `REVIEW_RARE_SPECIES` | `true` | Send unusual observations to the review queue |
| `SENSITIVE_LOCATION_RADIUS_KM` | `10` | Public coordinate-obscuring radius |
| `MAX_UPLOAD_MB` | `20` | Maximum size of each photo or audio upload |
| `SPECIES_LIST_PATH` | `data/species.csv` | Path to the project taxonomy file |
| `SMTP_URL` | — | SMTP connection URL for notifications |
| `LOG_LEVEL` | `INFO` | Application logging level |

A minimal production configuration might look like:

```dotenv
APP_ENV=production
SECRET_KEY=replace-with-a-long-random-value
DATABASE_URL=postgresql://birdwatch:password@localhost/birdwatch
PUBLIC_BASE_URL=https://survey.example.org
DEFAULT_TIMEZONE=America/Toronto
REQUIRE_EMAIL_VERIFICATION=true
SENSITIVE_LOCATION_RADIUS_KM=20
LOG_LEVEL=WARNING
```

Do not commit `.env` files, database credentials, uploaded evidence, or precise locations for sensitive species to version control.