{"id":41552694,"url":"https://github.com/lostbean/project51","last_synced_at":"2026-01-24T04:45:44.309Z","repository":{"id":286928485,"uuid":"961640046","full_name":"lostbean/project51","owner":"lostbean","description":"A nice stack example in the shape of a game","archived":false,"fork":false,"pushed_at":"2025-06-13T23:49:52.000Z","size":530,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-14T00:27:59.792Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/lostbean.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}},"created_at":"2025-04-06T23:17:41.000Z","updated_at":"2025-06-13T23:50:30.000Z","dependencies_parsed_at":"2025-04-09T03:28:16.558Z","dependency_job_id":"3e1acd48-f3a9-451b-aa28-0ba39cb756d0","html_url":"https://github.com/lostbean/project51","commit_stats":null,"previous_names":["lostbean/project51"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lostbean/project51","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lostbean%2Fproject51","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lostbean%2Fproject51/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lostbean%2Fproject51/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lostbean%2Fproject51/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lostbean","download_url":"https://codeload.github.com/lostbean/project51/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lostbean%2Fproject51/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28711962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T23:51:44.727Z","status":"online","status_checked_at":"2026-01-24T02:00:06.909Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-01-24T04:45:43.571Z","updated_at":"2026-01-24T04:45:44.300Z","avatar_url":"https://github.com/lostbean.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 👽 Area 51: Unveiling the Unknown 🕵️‍♀️\n\nWelcome to **Area 51: Unveiling the Unknown**, a real-time collaborative investigation game powered by Elixir, Phoenix, React, and Large Language Models (LLMs)! 🚀 Dive into the mysteries of Area 51, work with fellow investigators, and unravel the secrets hidden within this enigmatic location.\n\n## 🎮 The Game\n\nIn **Area 51: Unveiling the Unknown**, you and your team of investigators are tasked with uncovering the truth behind the legendary Area 51. 🕵️‍♂️ Collaborate in real-time, share your findings, and let the LLM-powered game master guide your investigation.\n\n### How to Play\n\n1.  **Join an Investigation:** Start a new investigation or join an existing one.\n2.  **Collaborate:** Share your observations, theories, and actions with your team.\n3.  **Interact with the LLM:** The game master, powered by an LLM, will dynamically respond to your inputs, evolving the narrative in real-time.\n4.  **Uncover Clues:** Discover hidden clues and piece together the puzzle.\n5.  **Solve the Mystery:** Work together to uncover the truth behind Area 51!\n\n## 🛠️ Tech Stack\n\n-   **Elixir \u0026 Phoenix:** Robust and scalable backend for real-time communication and application logic. ⚡\n-   **React:** Dynamic and responsive frontend for an engaging user experience. ⚛️\n-   **Phoenix Channels:** Real-time communication via WebSockets. 📡\n-   **LiveState:** Efficient state synchronization between the backend and frontend. 🔄\n-   **Ecto \u0026 SQLite:** Data persistence for game sessions, clues, and logs. 💾\n-   **Reactor Workflows:** Composable, type-safe workflow orchestration for AI and conventional processes. 🔄\n-   **Oban Job Management:** Reliable background job processing with telemetry and monitoring. ⚙️\n-   **Gleam:** Type-safe functional programming for state modeling. 🌟\n\n## 🧮 Architecture \u0026 Design\nSee the [deep search analysis](./Architecture_Deep_Search.md) for detailed exploration.\n\n### Key Architectural Changes\n\n-   **From Magus to Reactor:** All workflows now use [Reactor](https://hexdocs.pm/reactor/) for composable, type-safe process orchestration\n-   **Oban Integration:** Background job processing with comprehensive telemetry and real-time status updates\n-   **Reactor Observability:** Custom middleware providing OpenTelemetry tracing, structured logging, and telemetry events\n-   **PubSub-Driven UI:** Real-time updates flow from backend processes through PubSub to LiveState channels\n\n## System Architecture Overview\n\n```mermaid\ngraph TB\n    subgraph \"Area 51 Application\"\n        subgraph \"area51_web\"\n            web_app[Phoenix Web App]--hosts--\u003eassets[React Frontend]\n            web_app--uses--\u003echannels[Phoenix Channels]\n            web_app--validates--\u003eauth[Guardian Auth]\n            channels--connects--\u003elive_state[LiveState]\n        end\n\n        subgraph \"area51_core\"\n            domain[Domain Models]--defines--\u003egame_state[Game State]\n            domain--defines--\u003egame_session[Game Session]\n            domain--defines--\u003eclue[Clue]\n            domain--defines--\u003euser[User]\n        end\n\n        subgraph \"area51_data\"\n            repo[Ecto Repo]--uses--\u003eschemas[Database Schemas]\n            schemas--maps to--\u003edomain\n            repo--persists--\u003egame_sessions[Game Sessions]\n            repo--persists--\u003einvestigation_logs[Investigation Logs]\n            repo--persists--\u003eclues[Clues]\n            repo--persists--\u003eplayer_contributions[Player Contributions]\n        end\n\n        subgraph \"area51_llm\"\n            reactors[Reactor Workflows]--orchestrates--\u003einvestigation_reactor[Investigation Reactor]\n            reactors--orchestrates--\u003emystery_reactor[Mystery Generation Reactor]\n            investigation_reactor--generates--\u003enarrative[Narrative]\n            investigation_reactor--extracts--\u003enew_clues[Clues]\n            mystery_reactor--creates--\u003emystery_jobs[Mystery Jobs]\n        end\n\n        subgraph \"area51_jobs\"\n            oban[Oban Job Processing]--executes--\u003emystery_worker[Mystery Generation Worker]\n            oban--broadcasts--\u003epubsub[PubSub Events]\n            mystery_worker--uses--\u003emystery_reactor\n            pubsub--updates--\u003elive_state\n        end\n\n        subgraph \"area51_gleam\"\n            gleam_state[State Module]--provides--\u003etype_safe_models[Type-Safe Models]\n        end\n    end\n\n    external_llm[LLM Provider]--connects--\u003eagent\n    browser[Browser]--connects--\u003eassets\n    auth0[Auth0]--provides--\u003etokens[JWT Tokens]\n    tokens--validated by--\u003eauth\n\n    area51_core--informs--\u003earea51_gleam\n    area51_core--accessed by--\u003earea51_data\n    area51_core--used by--\u003earea51_web\n    area51_web--uses--\u003earea51_llm\n    area51_jobs--processes--\u003ebackground_tasks[Background Tasks]\n    area51_jobs--publishes to--\u003epubsub\n    live_state--synchronizes--\u003eassets\n    live_state--subscribes to--\u003epubsub\n    live_state--uses--\u003edomain\n    reactors--integrates with--\u003eoban\n```\n\n### Modularity and Separation of Concerns\n\nThe Area 51 project is structured as a single Elixir application, promoting clear separation of concerns through its modular design using namespaces under the main `Area51` module:\n\n-   **Area51.Core:** Contains the domain models and core game logic.\n-   **Area51.Data:** Handles data persistence using Ecto with job-specific schemas.\n-   **Area51.Jobs:** Manages background job processing with Oban, including job-specific contexts and telemetry.\n-   **Area51.Llm:** Encapsulates LLM integration using Reactor workflows for composable AI processes.\n-   **Area51.Web:** Manages HTTP and WebSocket interfaces with real-time PubSub integration.\n-   **Area51.Gleam:** Leverages Gleam for type-safe state modeling.\n-   **Reactor.Middleware:** Provides observability middleware for workflow tracing and monitoring.\n\nThis modular approach using namespaces within a single application facilitates testing, allows components to evolve with clarity, and supports system scalability.\n\n### State Management \u0026 Real-time Updates\n\nThe application implements a sophisticated state management strategy with comprehensive real-time capabilities:\n\n-   **Backend State:** Game state is maintained in the Elixir backend, using Phoenix PubSub for real-time updates\n-   **Frontend Synchronization:** LiveState library efficiently syncs backend state to the React frontend\n-   **Event-Based Architecture:** State changes are driven by events, with the system responding to player actions and job completions\n-   **Job-Driven Workflows:** Background jobs use Reactor workflows to orchestrate complex processes\n-   **PubSub Integration:** Job status changes and completions automatically broadcast to LiveState channels\n-   **Type-Safe State Modeling:** Gleam provides compile-time type safety for state definitions\n\nState flows from the backend to the frontend through Phoenix Channels and LiveState, creating a consistent, real-time experience for all players in an investigation.\n\n### Authentication \u0026 Authorization\n\nAuthentication and authorization are implemented using industry-standard patterns:\n\n-   **IDP-Based Authentication:** Integration with Auth0 provides secure authentication services\n-   **JWT-Based Authorization:** JSON Web Tokens handle authorization for protected resources\n-   **ETS Caching:** Erlang Term Storage provides fast, lightweight caching of validation keys\n-   **JWKS Integration:** Dynamic key fetching with ETS caching enables seamless key rotation support\n\nThe system validates JWTs using cached JWKS (JSON Web Key Sets), providing robust security with minimal performance overhead.\n\n### Observability \u0026 Monitoring\n\nComprehensive observability is achieved through multi-layered instrumentation with specialized workflow monitoring:\n\n-   **Telemetry:** Erlang/Elixir's telemetry library provides structured event emission\n-   **OpenTelemetry:** Standardized tracing across service boundaries and Reactor workflows\n-   **Reactor Middleware:** Custom observability middleware for workflow tracing, structured logging, and telemetry events\n-   **Job Telemetry:** Oban job lifecycle events with job-specific telemetry handlers\n-   **Structured Logging:** Consistent log formatting with contextual metadata and trace correlation\n-   **Metrics Collection:** PromEx integration for Prometheus-compatible metrics\n-   **Grafana Dashboards:** Pre-configured visualization for system performance and job monitoring\n\nTraces follow requests through the system, from HTTP requests through channel operations, Reactor workflows, to job processing and LLM interactions, providing end-to-end visibility into system behavior.\n\n### Language Interoperability\n\nThe project showcases seamless interoperation between multiple programming languages:\n\n-   **Elixir:** Powers the core application logic and backend services\n-   **Gleam:** Provides type-safe state modeling with compile-time guarantees\n-   **TypeScript:** Ensures type safety in the React frontend\n-   **JavaScript:** Supports the React component ecosystem\n\nThis polyglot approach leverages each language's strengths while maintaining clean integration points.\n\n## 🚀 Setup\n\n1.  **Prerequisites:**\n\n    You can install all the dependencies using [Nix](https://nixos.org/download/). Use the following command to enter the development shell:\n    ```bash\n    nix develop\n    ```\n\n2.  **Install Elixir and NPM Dependencies:**\n    ```bash\n    mix setup\n    ```\n\n3.  **Configure Auth0 environment and OpenAI key:**\n\n    Create a new Auth0 dev environment with SPA application type and callback `http://localhost:4000`. Make a copy of the `.env.example` file into `.env` and update the envars\n    according the values defined into your Auth0 environment.\n\n    Also include your OpenAI key in the `.env`, unless it's already part of your shell environment.\n\n4.  **Start the observability system:**\n    ```bash\n    docker-compose -f docker-compose.observability.yml up -d\n    ```\n\n5.  **Start the Area51 application:**\n    ```bash\n    mix phx.server\n    ```\n\n6.  **Access the Game:**\n    -   Open your web browser and navigate to `http://localhost:4000`.\n\n## 📂 Project Structure\n\n```\narea51_investigation/\n├── assets/                # Frontend assets (React, JavaScript, CSS)\n├── config/                # Application configurations\n├── lib/                   # Elixir application code\n│   └── area51/\n│       ├── core/          # Core game logic\n│       ├── data/          # Data persistence\n│       ├── gleam/         # Gleam integration\n│       ├── llm/           # LLM integration\n│       └── web/           # Phoenix web components (controllers, channels, etc.)\n├── priv/                  # Private application data\n│   ├── gettext/           # Localization files\n│   ├── repo/              # Ecto migrations and seeds\n│   └── static/            # Static assets (favicon, robots.txt, compiled JS/CSS in assets/)\n├── test/                  # Test files\n│   └── area51/\n│       ├── core/\n│       ├── data/\n│       ├── gleam/\n│       ├── llm/\n│       └── web/\n├── gleam_state/           # Gleam package for state modeling\n├── mix.exs                # Project configuration\n└── README.md              # Project documentation\n```\n\n**Note:** The Mermaid diagram above reflects the old umbrella structure and needs to be manually updated to represent the current single-application architecture with namespaced modules.\n\n## 🧠 LLM Integration \u0026 Workflow Orchestration\n\nThe `Area51.Llm` module handles LLM integration using Reactor workflows for composable, type-safe AI processes. 🚀\n\n-   **Reactor Workflows:** Composable workflow orchestration using [Reactor](https://hexdocs.pm/reactor/) for complex AI processes\n-   **Instructor Integration:** Structured LLM outputs using [Instructor](https://hexdocs.pm/instructor/) with Ecto schemas\n-   **Asynchronous Processing:** Background job processing with Oban for long-running AI operations\n-   **Observability:** Full tracing and monitoring of AI workflows through custom Reactor middleware\n-   **Job Management:** Mystery generation and other AI processes handled as background jobs with real-time status updates\n\n### Key Components\n\n-   **Investigation Reactor:** Orchestrates narrative generation and clue extraction workflows\n-   **Mystery Generation Reactor:** Handles complex mystery creation processes as background jobs\n-   **Reactor Middleware:** Provides OpenTelemetry tracing, structured logging, and telemetry events for all workflows\n\n## Deployment\n\nBuild a release image with:\n```bash\ndocker load \u003c $(nix build .\\#packages.aarch64-linux.image.area51.arm64 --no-link --print-out-paths)\ndocker run -e OPENAI_API_KEY=$OPENAI_API_KEY -p 4000:4000 -v area51db:/data area51:dirty\n```\n\n## 🤝 Contributing\n\nWe welcome contributions! Feel free to submit pull requests or open issues to improve the game. 🛠️\n\n## 📜 License\n\nThis project is licensed under the [MIT License](LICENSE). 📄\n\n---\n\nUncover the secrets of Area 51 and join the investigation! 🕵️‍♂️👽🚀\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flostbean%2Fproject51","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flostbean%2Fproject51","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flostbean%2Fproject51/lists"}