feat: initial release of Protocol Droid v0.2.0
A tool for authoring, sharing, and curating social protocols. Features: - Protocol library with search, tag filtering, and sort by date/relevance - Protocol authoring with structured fields (title, description, steps, outcome, practice, source, tags) - Protocol forking with provenance tracking - Collection creation with searchable protocol picker and ordering - User accounts with roles (admin, member, viewer) - YAML import/export for portability - Self-hostable on LAMP/Cloudron, works in subdirectories - Responsive design with hamburger menu on mobile - About page Security: - CSRF protection via Origin/Referer validation - Session regeneration on login/register - Secure session cookie params (HttpOnly, SameSite, Secure) - Visibility enforcement on private/unlisted items - YAML object injection hardening - Login rate limiting - Path traversal protection - Input validation and length clamping - Vote value constraining Stack: PHP 8.x + MySQL/MariaDB, vanilla JS frontend, no external dependencies. Hippocratic License (HL3-CORE).
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
# Protocol Droid
|
||||
|
||||
A tool for authoring, sharing, and curating social protocols.
|
||||
|
||||
A project of the [Media Economies Design Lab at the University of Colorado Boulder](https://MEDLab.host).
|
||||
|
||||
## Overview
|
||||
|
||||
Protocol Droid is a web application where communities can document, share, and remix patterns of interaction — social protocols. It is self-hostable, whitelabel-able, and designed for organizations that want a trustful commons without external dependencies.
|
||||
|
||||
## Features
|
||||
|
||||
- **Protocol library**: browse protocols with structured fields (title, description, steps, outcome, practice, source)
|
||||
- **Authoring**: create protocols through a form-based editor
|
||||
- **Forking**: adapt an existing protocol to your context while linking back to the original
|
||||
- **Collections**: curate sets of protocols and share them
|
||||
- **Identity**: user accounts with optional SSO support
|
||||
- **YAML import/export**: protocols are fully structured YAML — portable, git-diffable, human-readable
|
||||
- **Whitelabel**: customize site name, tagline, and theme via `config.yaml`
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
protocol-droid/
|
||||
├── api/ PHP backend (REST API)
|
||||
│ ├── index.php API router (all /api/* requests)
|
||||
│ ├── db.php Database connection + helpers (MySQL/MariaDB)
|
||||
│ ├── auth.php Session-based authentication
|
||||
│ ├── config.php Site configuration
|
||||
│ └── yaml.php YAML import/export helpers
|
||||
├── frontend/ Single-page frontend
|
||||
│ ├── index.html HTML shell
|
||||
│ ├── style.css R2-Rebel blend stylesheet
|
||||
│ └── app.js Application logic (vanilla JS)
|
||||
├── seeds/ Seed protocol YAML files
|
||||
│ ├── round-robin-check-in.yaml
|
||||
│ ├── consent-decision-making.yaml
|
||||
│ ├── appreciative-apology.yaml
|
||||
│ ├── temperature-reading.yaml
|
||||
│ ├── dot-voting.yaml
|
||||
│ └── fishbowl-discussion.yaml
|
||||
├── cloudron/ Cloudron deployment files
|
||||
│ └── CloudronManifest.json
|
||||
├── schema.sql MySQL database schema
|
||||
├── config.yaml Whitelabel configuration
|
||||
├── .htaccess Apache rewrite rules
|
||||
└── README.md This file
|
||||
```
|
||||
|
||||
## Stack
|
||||
|
||||
- **Backend**: PHP 8.x with PDO (MySQL/MariaDB)
|
||||
- **Database**: MySQL/MariaDB (Cloudron-native)
|
||||
- **Frontend**: Vanilla HTML/CSS/JS — no frameworks, no build step, no external dependencies
|
||||
- **Data format**: YAML for portability, MySQL for runtime
|
||||
- **Auth**: Session-based with optional SSO
|
||||
|
||||
## Deployment
|
||||
|
||||
### On Cloudron
|
||||
|
||||
1. Create a LAMP app in Cloudron
|
||||
2. Upload all files to the app's web root
|
||||
3. The database schema auto-initializes on first API request
|
||||
4. Visit the site and register — the **first user to register becomes admin**
|
||||
5. Optionally load seed protocols: sign in as admin and `POST /api/seed` (or use the API endpoint with curl: `curl -b cookies.txt -X POST https://your-site/api/seed`)
|
||||
|
||||
**No default admin credentials exist.** A fresh deployment has an empty database. The first registration creates the admin account. Seed protocols are optional and must be explicitly loaded.
|
||||
|
||||
### On any LAMP server
|
||||
|
||||
1. Upload files to your web root (or a subdirectory like `/protocol-droid/`)
|
||||
2. Create a MySQL database and user
|
||||
3. Set environment variables (or edit `api/db.php`):
|
||||
- `MYSQL_HOST`, `MYSQL_PORT`, `MYSQL_DATABASE`, `MYSQL_USER`, `MYSQL_PASSWORD`
|
||||
4. Visit the site and register — first user becomes admin
|
||||
|
||||
**Subdirectory deployment:** Protocol Droid works in a subdirectory (e.g. `example.com/protocol-droid/`). The root `index.php` auto-detects the base path from the server's script name. No configuration needed — just upload the files to the subdirectory and ensure `index.php` is served as the directory index (most LAMP setups do this by default with `DirectoryIndex index.php` or `.htaccess`).
|
||||
|
||||
### Local development
|
||||
|
||||
```bash
|
||||
# Start PHP built-in server
|
||||
cd protocol-droid
|
||||
php -S localhost:8000
|
||||
|
||||
# Or with a MySQL database:
|
||||
MYSQL_HOST=localhost MYSQL_DATABASE=protocol_droid MYSQL_USER=root MYSQL_PASSWORD=secret php -S localhost:8000
|
||||
```
|
||||
|
||||
The first registration creates the admin account. To load the 6 sample protocols (Round Robin Check-In, Consent Decision-Making, etc.):
|
||||
|
||||
```bash
|
||||
# After registering as admin:
|
||||
curl -c cookies.txt -X POST http://localhost:8000/api/auth/login \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"username":"your-username","password":"your-password"}'
|
||||
|
||||
curl -b cookies.txt -X POST http://localhost:8000/api/seed
|
||||
```
|
||||
|
||||
To remove all seed protocols (or any protocols), delete them individually:
|
||||
|
||||
```bash
|
||||
curl -b cookies.txt -X DELETE http://localhost:8000/api/protocols/round-robin-check-in
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
| Endpoint | Method | Description | Auth |
|
||||
|----------|--------|-------------|------|
|
||||
| `/api` | GET | API info | none |
|
||||
| `/api/config` | GET | Site configuration | none |
|
||||
| `/api/protocols` | GET | List public protocols | none |
|
||||
| `/api/protocols/:slug` | GET | Get protocol | none |
|
||||
| `/api/protocols` | POST | Create protocol | member |
|
||||
| `/api/protocols/:slug` | PUT | Update protocol | author/admin |
|
||||
| `/api/protocols/:slug` | DELETE | Delete protocol | author/admin |
|
||||
| `/api/protocols/:slug/yaml` | GET | Export as YAML | none |
|
||||
| `/api/collections` | GET | List collections | none |
|
||||
| `/api/collections/:slug` | GET | Get collection | none |
|
||||
| `/api/collections` | POST | Create collection | member |
|
||||
| `/api/collections/:slug` | PUT | Update collection | author/admin |
|
||||
| `/api/collections/:slug` | DELETE | Delete collection | author/admin |
|
||||
| `/api/auth/register` | POST | Register | none |
|
||||
| `/api/auth/login` | POST | Login | none |
|
||||
| `/api/auth/logout` | POST | Logout | none |
|
||||
| `/api/auth/me` | GET | Current user | none |
|
||||
| `/api/users/:username` | GET | Public profile | none |
|
||||
| `/api/votes` | POST | Vote on protocol | member |
|
||||
| `/api/export` | GET | Export all as YAML | admin |
|
||||
| `/api/import` | POST | Import YAML | admin |
|
||||
| `/api/seed` | POST | Load seed protocols | admin |
|
||||
|
||||
## Protocol YAML Format
|
||||
|
||||
```yaml
|
||||
id: round-robin-check-in
|
||||
title: Round Robin Check-In
|
||||
description: >-
|
||||
A structured way for each person in a group to share briefly.
|
||||
source: Group Works Deck
|
||||
source_url: https://groupworksdeck.org/deck
|
||||
tags: [check-in, facilitation]
|
||||
forked_from: null
|
||||
image: null
|
||||
steps:
|
||||
- headline: Frame the round
|
||||
description: >-
|
||||
The facilitator explains that each person will have up to one minute.
|
||||
- headline: Go around
|
||||
description: >-
|
||||
Each person speaks in turn. Passing is always an option.
|
||||
outcome: >-
|
||||
Everyone has been heard; the group has a shared sense of where things stand.
|
||||
practice: >-
|
||||
Use a talking object. Keep time gently. For large groups, break into smaller rounds.
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Hippocratic License (HL3-CORE) — do no harm. See https://firstdonoharm.dev/
|
||||
|
||||
## Roadmap
|
||||
|
||||
- **SSO / OIDC** — The database schema and user table include `sso_provider` and `sso_id` fields, and the auth API has a placeholder SSO endpoint. Full OIDC provider support (university SSO, Google Workspace, etc.) is planned but not yet implemented.
|
||||
- **Bicorder integration** — Connecting Protocol Droid with the [Protocol Bicorder](https://git.medlab.host/ntnsndr/protocol-bicorder) diagnostic tool, so protocols can be evaluated along gradient dimensions.
|
||||
- **Voting / evaluation** — The `votes` table exists in the schema but the UI for voting on protocols is not yet built.
|
||||
- **Image support** — The protocol and collection schemas include an `image` field, but image upload and display are not yet implemented.
|
||||
Reference in New Issue
Block a user