{"id":34777591,"url":"https://github.com/thecodemonkey/truegotham","last_synced_at":"2026-05-23T08:02:38.156Z","repository":{"id":320736331,"uuid":"1083174974","full_name":"thecodemonkey/truegotham","owner":"thecodemonkey","description":"truegotham is a web application that reads the current crimes from the police press releases, analyzes them using AI and displays them on a dashboard.","archived":false,"fork":false,"pushed_at":"2026-01-27T18:47:06.000Z","size":197878,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-27T20:19:45.420Z","etag":null,"topics":["ai","kotlin","vanilla"],"latest_commit_sha":null,"homepage":"https://truegotham.thecodemonkey.de/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thecodemonkey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-25T13:49:35.000Z","updated_at":"2026-01-27T17:16:13.000Z","dependencies_parsed_at":"2025-10-25T16:26:00.781Z","dependency_job_id":"6068f899-ca43-4732-95ec-595d9a0b2ddf","html_url":"https://github.com/thecodemonkey/truegotham","commit_stats":null,"previous_names":["thecodemonkey/truegotham"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/thecodemonkey/truegotham","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodemonkey%2Ftruegotham","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodemonkey%2Ftruegotham/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodemonkey%2Ftruegotham/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodemonkey%2Ftruegotham/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thecodemonkey","download_url":"https://codeload.github.com/thecodemonkey/truegotham/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thecodemonkey%2Ftruegotham/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33387656,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","kotlin","vanilla"],"created_at":"2025-12-25T08:37:27.196Z","updated_at":"2026-05-23T08:02:38.151Z","avatar_url":"https://github.com/thecodemonkey.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# truegotham\n\ntruegotham is a web application that reads the current crimes from the police press releases, analyzes them using AI and displays them on a dashboard. \n\nhttps://truegotham.thecodemonkey.de/\n\n## Table of Contents\n\n* [Motivation](#motivation)\n* [Quickstart](#quickstart)\n* [How it works](#how-it-works)\n  * [Data Processing Flow](#data-processing-flow)\n  * [Crawler](#crawler)\n  * [Import Pipeline](#import-pipeline)\n* [Frontend](#frontend)\n* [Project Structure](#project-structure)\n* [TechStack](#techstack)\n\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n## Motivation\n\nAs a fan of true crime and \"Tatort\", I wanted to combine interest with practice and deepen my AI skills through a real-world project. This project serves as a playground for me to experiment with approaches like advanced prompt engineering, image generation, and agentic AI in a practical setting. It allows me to explore new models and test various GenAI methods using a real-world scenario. Ultimately, it’s a straightforward way for me to stay up-to-date technically while building something I'm personally interested in.\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n## Quickstart\n\n### Prerequisites\n\n*   **Java 21**: You need JDK 21 installed.\n*   **OpenAI API Key**: The application requires an OpenAI API key to function. Set the environment variable `AI_API_KEY` to your key.\n\n### Start\n\n1. Clone the GitHub repository:\n   ```bash\n   git clone https://github.com/thecodemonkey/truegotham.git\n   cd truegotham\n   ```\n2. Start the application:\n   ```bash\n   ./gradlew bootRun\n   ```\n3. Open the dashboard in your browser:\n   [http://localhost:7171](http://localhost:7171)\n\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n## How it works\n\ntruegotham reads the current crimes from the [police press releases](https://www.presseportal.de/blaulicht/nr/4971), analyzes them using AI and displays them on a dashboard. Due to the enormity of data and the associated costs, only press releases from the Dortmund region are used at the moment.\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n### Data Processing Flow\n\n```mermaid\ngraph TD\n    \n        PP[https://presseportal.de/blaulicht/]\n    \n\n    subgraph Backend [backend processing]\n        Crawler[Crawler / *Playwright*]\n        RawDB[(Raw Data Storage)]\n        \n        subgraph Pipeline[import pipeline]\n            direction TB\n            P1[\u003ccode\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Initial Import\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003c/code\u003e]\n            P2{\u003ccode\u003eCrime Classification\u003c/code\u003e\u003cbr/\u003eAI Filter}\n            P3{\u003ccode\u003eLocation Extraction \u003c/code\u003e\u003cbr/\u003eRegion Filter}\n            P4[\u003ccode\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;Summary Creation\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003c/code\u003e]\n            P5[\u003ccode\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;Cover Image Gen\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003c/code\u003e]\n            P6[\u003ccode\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;Offender Profile\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003c/code\u003e]\n            P7[\u003ccode\u003e\u0026nbsp;\u0026nbsp;Offender Image Gen\u0026nbsp;\u0026nbsp;\u003c/code\u003e]\n            P8[\u003ccode\u003e\u0026nbsp;\u0026nbsp;Criminal Offences\u0026nbsp;\u0026nbsp;\u003c/code\u003e]\n            P9[\u003ccode\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;Evidence \u0026 Tools\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003c/code\u003e]\n            P10[\u003ccode\u003e\u0026nbsp;Motivation Analysis\u0026nbsp;\u003c/code\u003e]\n            P11[\u003ccode\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Finalization\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003c/code\u003e]\n            \n            Discard([Discard Irrelevant])\n        end\n        \n        AI[AI Engine \u003cbr/\u003e OpenAI / LLMs]\n\n        IncidentDB[(Structured Incidents)]\n    end\n\n\n    \n\n    Frontend[Web Application]\n\n    %% Main Flow\n    PP --\u003e|crawl| Crawler\n    Crawler --\u003e|store| RawDB\n    RawDB --\u003e|trigger| P1\n    \n    %% Pipeline Flow\n    P1 --\u003e P2\n    P2 --\u003e|relevant| P3\n    P2 --\u003e|irrelevant| Discard\n    \n    P3 --\u003e|in-region| P4\n    P3 --\u003e|out-of-region| Discard\n    \n    P4 --\u003e P5 --\u003e P6 --\u003e P7 --\u003e P8 --\u003e P9 --\u003e P10 --\u003e P11\n    \n    %% AI Integration\n    Pipeline \u003c--\u003e AI\n    \n    %% Storage \u0026 UI\n    P11 --\u003e|store| IncidentDB\n    IncidentDB --\u003e|visualize| Frontend\n```\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n### Crawler\n\nThe crawler is a Service that uses Playwright to crawl the police press releases from https://presseportal.de/blaulicht/ and stores the raw data in a database.\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n### Import Pipeline\n\nThe pipeline is a series of steps that process the data and store it in a database. The pipeline is implemented as a series of steps that are executed in a specific order. The steps are:\n\n1. Initial Import\n2. Crime Classification\n3. Location Extraction\n4. Summary Creation\n5. Cover Image Generation\n6. Offender Profile\n7. Offender Image Generation\n8. Criminal Offences\n9. Evidence \u0026 Tools\n10. Motivation Analysis\n11. Finalization\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n## Frontend Stack\n\nI consciously chose a **Vanilla JS/HTML/CSS** stack for this project. This approach is extremely lightweight and minimizes abstraction layers compared to heavy frameworks like Angular or the complexity of TypeScript. \n\nBeyond the simplicity of manual coding, this setup is particularly optimized for **AI Coding Assistants and Agents** (like GitHub Copilot or Antigravity). Without the overhead of complex framework, npm, yarn, nx, lifecycles, build steps, or deep abstractions, AI agents can generate bug-free code much faster and handle the codebase more effectively.\n\nAdditionally, this architecture eliminates the need for a separate frontend project or complex build pipeline. The frontend is directly embedded in the Spring Boot `static` folder, allowing for a **unified deployment** of both backend and frontend as a single artifact. This drastically simplifies the deployment setup and CI/CD process. For projects of this scale or specialized tools, this \"back-to-basics\" approach provides a highly productive and performant environment.\n\n\u003e **Note:** While I still prefer the Vanilla stack, I am increasingly moving towards augmenting it with standard **WebComponents** and **Lit**. `truegotham` has not yet been refactored, but I may do so in the future. This combination has personally emerged as the \"ultimate\" frontend stack for simple projects, especially when combined with AI coding agents.\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n## Project Structure\n\n```text\ntruegotham/\n├── src/main/kotlin/.../truegotham/\n│   ├── import/          # Core pipeline logic and ImportFlow steps\n│   ├── service/         # AI connectors, Crawler (Playwright), and Geocoding\n│   ├── model/           # Entity definitions and structured AI result models\n│   ├── controller/      # REST endpoints for the dashboard\n│   ├── repository/      # Database access (H2/Filesystem persistence)\n│   ├── config/          # Bean configurations and security settings\n│   └── utils/           # Shared helper classes and extensions\n├── src/main/resources/\n│   ├── static/          # Vanilla JS Frontend (embedded in Spring Boot)\n│   │   ├── components/  # Modular dashboard UI components\n│   │   └── index.html   # Main entry point for the Web Application\n│   ├── prompts/         # Specialized text templates for LLM reasoning\n│   ├── data/            # Static data lookups (e.g., district geojson or mappings)\n│   └── application.yml  # System configuration and API settings\n├── data/                # H2 Database location on dev machine\n├── Dockerfile           # Environment setup for deployment (Docker/K8s)\n└── build.gradle         # Dependency management (Kotlin/Spring Boot)\n```\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n## TechStack\n\n*   **Backend:** Kotlin, Spring\n*   **Frontend:** Vanilla HTML/CSS/JS\n*   **AI:** OpenAI, gpt-4.x/5.x, gpt-image-1\n*   **MAP:** Leaflet, OpenStreetMap\n*   **Database:** H2/filesystem\n*   **Deployment:** Docker, Kubernetes\n*   **CI/CD:** GitHub Actions, GitHub Container Registry\n*   **IDE:** IntelliJ IDEA/GitHub Copilot and Antigravity/Gemini\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthecodemonkey%2Ftruegotham","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthecodemonkey%2Ftruegotham","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthecodemonkey%2Ftruegotham/lists"}