Skip to content

About

View all your posted stickers on a map

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Repository files navigation

Build Status Latest Release AGPL3 License Stars Last Commit Issues Open PRs

A web application for uploading, viewing, and managing sticker locations across the world with automatic GPS extraction from images.

Quick Start

Prerequisites

  • Podman
  • At least 4 GB of available RAM
  • Ports 5432, 5555, 8080, 8181, and 8282 available

Start the application

compose.yml builds all services from local source and imports the bundled Keycloak realm automatically:

podman compose up -d

Wait 30–60 seconds for all services to initialize.

Access the application:

Service URL
Application https://localhost:8282
API docs (Swagger) http://localhost:5555/api/v1/docs
Keycloak Admin https://localhost:8282/auth

Stop:

podman compose down

Architecture

graph TD
    Browser["Browser\n(Angular + MapLibre GL)"]
    Backend["Backend\n(FastAPI)"]
    DB["PostgreSQL + PostGIS"]
    KC["Keycloak"]

    Browser -->|"REST / JSON + JWT"| Backend
    Backend --> DB
    Browser <-->|"OIDC"| KC
    Backend -->|"JWKS key fetch"| KC
Loading

Technology Stack

Layer Technology
Frontend Angular 22 (zoneless), TypeScript 6.0, MapLibre GL 6.x
Backend Python 3.14, FastAPI, Pydantic
Database PostgreSQL with PostGIS (SRID 4326)
Authentication Keycloak, JWT RS256

Authentication

StickerMap uses Keycloak with four hierarchical client roles (scoped to the stickermap-client client):

Role Permissions
sm-viewer View sticker details
sm-uploader Upload stickers, edit own stickers
sm-editor Edit any sticker's poster, date, and location
sm-admin Full access — edit all fields, delete stickers

Each role includes all permissions of the roles below it (composite roles).

Authentication flow:

sequenceDiagram
    participant User
    participant App as Angular App
    participant KC as Keycloak
    participant API as FastAPI

    User->>App: Navigate to /add-sticker
    App->>KC: Redirect (OIDC / silent SSO check)
    KC->>App: JWT access token
    App->>API: Request + Bearer token
    API->>KC: Fetch JWKS public keys
    API->>App: 200 OK / 401 / 403
Loading

For full Keycloak setup and manual role configuration see docs/authentication.md.

Development

See the individual module READMEs for detailed setup:

Backend quick setup
cd backend
uv sync

# Start dependencies
podman network create stickermap
podman run --name stickermap-postgis -d --network stickermap -p 5432:5432 \
  -e POSTGRES_USER=user -e POSTGRES_PASSWORD=password -e POSTGRES_DB=stickermap \
  docker.io/postgis/postgis:18-3.6
podman run --name stickermap-keycloak -d --network stickermap -p 8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:26.5 start-dev

cp .env.example .env
cd ../database_migrations && uv run alembic upgrade head && cd ../backend
uv run fastapi dev main.py --port 5555

Backend: http://localhost:5555

Frontend quick setup
cd frontend
pnpm install
pnpm start

Frontend: http://localhost:4200

Kubernetes

A Helm chart is available at helm/stickermap/. It requires Helm v4 and has no chart dependencies — all templates are inlined (air-gap friendly).

The chart deploys the backend, frontend, and a one-shot migration Job. The PostgreSQL/PostGIS database and Keycloak are not included — bring your own and reference them via values.

See helm/README.md for mandatory values, configuration examples, and OCI packaging instructions.

Troubleshooting

See docs/troubleshooting.md for a full reference.

Common issues

Port conflicts — change port mappings in compose.yml.

Database connection errors:

podman ps | grep stickermap-postgis
podman compose restart backend

Keycloak authentication fails:

podman ps | grep stickermap-keycloak
# Verify realm and client exist in the admin console
# Clear browser localStorage if stuck in redirect loop

Token validation fails (401):

# Verify JWKS endpoint is reachable
curl http://localhost:8080/realms/stickermap/protocol/openid-connect/certs
# Check KEYCLOAK_URL in backend/.env

Image upload fails — check file size (max 16 MB) and type (JPEG, PNG, GIF, WebP).

No GPS data extracted — use original camera photos; many platforms strip EXIF on upload.

Map not loading — check browser console for errors; verify MapLibre GL is loading and tile requests are succeeding in the network tab. A blank map with a 404 for maplibre-gl-worker.mjs means the MapLibre v6 web worker is not being served — see the MapLibre section in CLAUDE.md.

Enable verbose backend logging:

# backend/.env
LOG_LEVEL=DEBUG

Additional Resources

AI-Assisted Development

This codebase is developed with the assistance of Anthropic's Claude, primarily through Claude Code. Project-scoped configuration for Claude Code (shared permissions, subagents, slash commands, and hooks) lives under .claude/, and conventions Claude follows when working in this repo are documented in CLAUDE.md.

License

See LICENSE for details.

About

View all your posted stickers on a map

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages