PHPackages                             markaspot/mark-a-spot - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. markaspot/mark-a-spot

ActiveProject[Utility &amp; Helpers](/categories/utility)

markaspot/mark-a-spot
=====================

Mark-a-Spot is a Drupal distribution for crowdmapping and public civic issue tracking

11.7.6(6mo ago)701.1k33[1 issues](https://github.com/markaspot/mark-a-spot/issues)[1 PRs](https://github.com/markaspot/mark-a-spot/pulls)GPL-2.0-or-laterPHPCI passing

Since Nov 14Pushed 3d ago7 watchersCompare

[ Source](https://github.com/markaspot/mark-a-spot)[ Packagist](https://packagist.org/packages/markaspot/mark-a-spot)[ RSS](/packages/markaspot-mark-a-spot/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (27)Versions (43)Used By (0)

Mark-a-Spot
===========

[](#mark-a-spot)

 [![Mark-a-Spot Logo](https://camo.githubusercontent.com/0ee4d614839bf5195046b2be09d972f4f14b25a3c42e9054804cfde31ec749bd/68747470733a2f2f7777772e6d61726b6173706f742e64652f6173736574732f696d616765732f6c6f676f2e737667)](https://camo.githubusercontent.com/0ee4d614839bf5195046b2be09d972f4f14b25a3c42e9054804cfde31ec749bd/68747470733a2f2f7777772e6d61726b6173706f742e64652f6173736574732f696d616765732f6c6f676f2e737667)### Open-Source Civic Issue Tracking and Open311 Platform for Drupal 11

[](#open-source-civic-issue-tracking-and-open311-platform-for-drupal-11)

[![Docker Image CI](https://github.com/markaspot/mark-a-spot/actions/workflows/docker-image.yml/badge.svg)](https://github.com/markaspot/mark-a-spot/actions/workflows/docker-image.yml)[![License: GPL v2+](https://camo.githubusercontent.com/ec6306119631a4bc812f4abc1b429674bd65410ae0ef38af01f43483fccc51ce/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c25323076322532422d626c75652e737667)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)[![Drupal: 11](https://camo.githubusercontent.com/c24b258c54a6e83cf0d670dce28f03c6ca29ec82c4965a9a38f342a6a41bbe24/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f44727570616c2d31312d627269676874677265656e2e737667)](https://www.drupal.org/project/markaspot)

### Key Features

[](#key-features)

- **Citizen Engagement:**
    An intuitive interface lets citizens report issues easily—complete with photos, detailed descriptions, and geolocation data—to ensure that community problems are visible and actionable.
- **Nuxt.js Decoupled Frontend:**
    A dynamic frontend, built with Nuxt.js, offers a sleek, responsive, and engaging user experience. It seamlessly complements the Drupal administration backend, creating an integrated platform designed for modern civic engagement.
- **Advanced Mapping &amp; Geolocation:**
    Interactive maps allow users to pinpoint exact problem locations, making it easier for public authorities to identify and respond to issues efficiently.
- **Open311 Compliant API:**
    The platform offers a standardized [GeoReport v2 API](https://wiki.open311.org/GeoReport_v2) for seamless integration with mobile applications, municipal services, and third-party systems.
- **Efficient Workflow Management:**
    Built-in tools help municipal staff manage issue submissions, track progress, and assign tasks, ensuring that problems are addressed from reporting to resolution.
- **Multi-language &amp; Localization Support:**
    With built-in support for multiple languages and region-specific configurations, the platform can be tailored to local needs and global standards.
- **Data-driven Insights:**
    Analytics and reporting tools provide actionable insights, helping decision-makers prioritize resources and plan improvements effectively.
- **Customizable &amp; Extensible:**
    Drupal's flexible architecture allows municipalities to customize workflows, integrate additional features, and expand functionality to suit diverse requirements.

### Who Uses Mark-a-Spot?

[](#who-uses-mark-a-spot)

Mark-a-Spot is designed for:

- **Municipal Governments &amp; City Administrations:**
    To streamline citizen reporting and improve the management of civic issues.
- **Public Service Departments:**
    To enhance coordination and responsiveness in public service delivery.
- **Community Organizations:**
    To foster a participatory approach in addressing local issues.
- **Civic Tech Innovators:**
    To leverage an adaptable, open-source solution for developing and deploying civic technologies.

Architecture
------------

[](#architecture)

Mark-a-Spot uses a **decoupled/headless architecture** with Drupal as the backend API server and a modern JavaScript frontend.

```
┌─────────────────────────────────────────────────────────────┐
│                     Frontend (PWA)                          │
│         Vue 3 · TypeScript · Tailwind · MapLibre            │
│                                                             │
│     Components ─── Stores (Pinia) ─── API Composables       │
└─────────────────────────────┬───────────────────────────────┘
                              │
                    HTTPS/JSON (REST)
                              │
┌─────────────────────────────▼───────────────────────────────┐
│                      Drupal 11 Backend                      │
│              PHP 8.3 · MySQL · Search API                   │
│                                                             │
│  ┌──────────────────────┐  ┌──────────────────────┐         │
│  │     Open311 API      │  │       JSON:API       │         │
│  │     (GeoReport)      │  │        (CRUD)        │         │
│  └──────────────────────┘  └──────────────────────┘         │
└─────────────────────────────────────────────────────────────┘

```

The backend exposes two APIs:

- **Open311 GeoReport v2** – Standardized civic issue API for reading/writing service requests
- **JSON:API** – Drupal's RESTful API for content management

Requirements
------------

[](#requirements)

- **PHP** 8.3+
- **Node.js** 22+ (LTS)
- **MySQL** 8.0+ or MariaDB 10.6+
- **Composer** 2.x

Getting Started
---------------

[](#getting-started)

These instructions will guide you through getting a copy of the project up and running on your local machine for development and testing purposes.

### Prerequisites

[](#prerequisites)

Install one (or both) of the following toolchains before you begin:

- [DDEV](https://ddev.readthedocs.io/en/stable/users/install/ddev-installation/) – recommended local development environment built on Docker
- Docker and Docker Compose (v2 `docker compose` CLI works too)

Installation
------------

[](#installation)

**Quick start (DDEV)** *(requires DDEV to be installed first)*

```
git clone https://github.com/markaspot/mark-a-spot.git
cd mark-a-spot
ddev start
ddev ssh
./scripts/start.sh -y
exit
```

After installation, access:

- **Backend (Drupal):**
- **Frontend (UI):**
- **Admin login:** Run `ddev drush uli` to get a one-time login link

### Which environment should I use?

[](#which-environment-should-i-use)

- **DDEV** – best for day-to-day development, automatic HTTPS, and a config you can share with teammates.
- **Docker Compose** – mirrors the legacy stack; handy if you need to run the shipped `docker-compose.yml` as-is.

> The installer always drops and recreates the Drupal database. Back up any local work before rerunning it.

### Installer flags (all environments)

[](#installer-flags-all-environments)

- `-y` Autopilot: uses default New York coordinates/locale and skips prompts.
- `-t` Drupal translation import: installs language packs from `translations/`.
- `-a` AI translation: runs `ai-translate.sh` to translate default content (needs `OPENAI_API_KEY`).
- Combine as needed, e.g. `./scripts/start.sh -t -a` for a multilingual build.
- On first run the installer generates a fresh GeoReport API key and prints it. To reuse a specific key, set `GEOREPORT_API_KEY` in your environment or `.env` before launching the installer (Docker/DDEV front-end services read the same variable).

### AI Translation Feature

[](#ai-translation-feature)

The (AI) translation feature allows you to automatically translate the Drupal UI and content artifacts (taxonomy terms, pages, blocks, etc.) using OpenAI's language models. This provides translations for your Mark-a-Spot installation's default content.

To use this feature:

- Run `./scripts/start.sh -t -a` to use both standard Drupal translation files and AI translation for content
- You'll need an OpenAI API key, which you can either:
    - Set as an environment variable: `export OPENAI_API_KEY=your_api_key`
    - Enter when prompted during the installation process

The `-t -a` option will:

1. Install the selected language in Drupal
2. Import standard translation files for the Drupal interface
3. Use AI to translate all default content to the selected language
4. Set up the site with the translated content as the default content

The translation covers:

- Taxonomy terms (categories, statuses, providers)
- Static pages (About, Contact, etc.)
- Boilerplate content
- Block content

Once the script has executed, the application should be accessible at  or the ddev URLs you will be retrieve via `ddev describe`.

Please exercise caution when executing the script, as it will drop the database and initialize Mark-a-Spot from scratch. Additionally, familiarize yourself with the Drupal development process, including configuring changes, backing up databases, and other relevant procedures.

### AI Photo Analysis (`markaspot_vision`)

[](#ai-photo-analysis-markaspot_vision)

The `markaspot_vision` module analyzes citizen-uploaded report photos with a vision LLM: it suggests a category, drafts a description and alt text, and flags potential hazards (CAP severity) and privacy concerns. It is **opt-in** and not part of the lean default install.

Enable it by exporting an OpenAI (or OpenAI-compatible) API key **before** running the installer:

```
export OPENAI_API_KEY=sk-your_api_key
./scripts/start.sh -y
```

When `OPENAI_API_KEY` is set, the installer enables `markaspot_vision` (+ `markaspot_ai`) and writes the key into `markaspot_vision.settings:api_key`. To enable the module without a key (e.g. to configure it later in the UI), pass it via `MARKASPOT_EXTRA_MODULES="markaspot_vision markaspot_ai"`.

**Key and endpoint** live in `markaspot_vision.settings` and can be changed after install with drush:

SettingDefaultPurpose`api_key`*(empty)*Bearer token sent to the vision endpoint (set from `OPENAI_API_KEY`).`api_url``https://api.openai.com/v1/chat/completions`Chat-completions endpoint. Point it at any OpenAI-compatible API (Azure OpenAI, a self-hosted/local LLM, etc.).`ai_model``gpt-4.1-mini`Vision-capable model id.```
# Change the endpoint and model after install:
ddev drush cset markaspot_vision.settings api_url 'https://your-host/v1/chat/completions' -y
ddev drush cset markaspot_vision.settings ai_model 'gpt-4.1-mini' -y
```

The default install ships **without** the analytical modules (`markaspot_vision`, `markaspot_escalation`, `markaspot_moderation`, `markaspot_notification`). Enable any of them on demand with `MARKASPOT_EXTRA_MODULES="..."` before running the installer.

#### Docker Compose workflow

[](#docker-compose-workflow)

1. Clone this repository (if you haven't already):

    ```
    git clone https://github.com/markaspot/mark-a-spot.git
    cd mark-a-spot
    ```
2. Start the stack:

    ```
    docker-compose up -d
    ```
3. Run the installer:

    If the script is not executable, make it so with `chmod a+x ./scripts/start.sh`.

    ```
    docker exec -it markaspot ./scripts/start.sh -y
    ```

Environment Variables
---------------------

[](#environment-variables)

Key environment variables for deployment:

VariableDescriptionExample`GEOREPORT_API_KEY`API key for GeoReport v2 authentication`abc123...``DRUPAL_DATABASE_*`Database connection settingsSee `env.example``OPENAI_API_KEY`Enables AI photo analysis (`markaspot_vision`) and the `-a` AI translation flag; also written to `markaspot_vision.settings:api_key``sk-...``MARKASPOT_EXTRA_MODULES`Space-separated list of opt-in modules to enable during install (e.g. `markaspot_escalation`)`markaspot_vision markaspot_ai`The installer generates a fresh `GEOREPORT_API_KEY` on first run. To use a specific key, set it before installation. See [AI Photo Analysis](#ai-photo-analysis-markaspot_vision) for the vision endpoint/model settings.

API Documentation
-----------------

[](#api-documentation)

Mark-a-Spot implements the [Open311 GeoReport v2](https://wiki.open311.org/GeoReport_v2) standard.

**Endpoints:**

- `GET /georeport/v2/services.json` – List available service categories
- `GET /georeport/v2/requests.json` – List service requests
- `GET /georeport/v2/requests/{id}.json` – Get single request
- `POST /georeport/v2/requests.json` – Create new request

**Authentication:**

- **Read**: API key via `api_key` parameter or header
- **Write**: Anonymous (with CSRF token) or authenticated session

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit issues and pull requests.

- **Issues**: [GitHub Issues](https://github.com/markaspot/mark-a-spot/issues)
- **Profile**: [markaspot/markaspot](https://github.com/markaspot/markaspot)

License
-------

[](#license)

Mark-a-Spot is freely available under the [GNU General Public License, version 2 or any later version](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) license.

###  Health Score

56

—

FairBetter than 97% of packages

Maintenance84

Actively maintained with recent releases

Popularity31

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 98.2% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~94 days

Recently: every ~11 days

Total

36

Last Release

204d ago

Major Versions

8.5.0-beta1 → 10.6.0-alpha.12023-12-05

10.6.0-beta.4 → 11.7.0-beta.12025-03-31

### Community

Maintainers

![](https://www.gravatar.com/avatar/0b778d53cdba174054bedcfac892e41e8c52c341b02a87bb38df80d373dd301b?d=identicon)[markaspot](/maintainers/markaspot)

---

Top Contributors

[![markaspot](https://avatars.githubusercontent.com/u/212898?v=4)](https://github.com/markaspot "markaspot (322 commits)")[![acouch](https://avatars.githubusercontent.com/u/512243?v=4)](https://github.com/acouch "acouch (3 commits)")[![bfabio](https://avatars.githubusercontent.com/u/788293?v=4)](https://github.com/bfabio "bfabio (1 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![huasamacocl](https://avatars.githubusercontent.com/u/51433076?v=4)](https://github.com/huasamacocl "huasamacocl (1 commits)")

### Embed Badge

![Health badge](/badges/markaspot-mark-a-spot/health.svg)

```
[![Health](https://phpackages.com/badges/markaspot-mark-a-spot/health.svg)](https://phpackages.com/packages/markaspot-mark-a-spot)
```

###  Alternatives

[govcms/govcms

GovCMS Drupal Distribution

197100.6k3](/packages/govcms-govcms)[fourkitchens/sous-drupal-project

Starter project for Sous a Drupal distribution featuring a theme based on Emulsify Design System.

141.1k](/packages/fourkitchens-sous-drupal-project)[goalgorilla/open_social

Open Social is a distribution for building social communities and intranets.

190461.9k](/packages/goalgorilla-open-social)[vardot/varbase-project

Project template for Varbase distribution.

5162.4k](/packages/vardot-varbase-project)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
