{"id":30071154,"url":"https://github.com/psyhackological/shuttle-shellcon","last_synced_at":"2025-08-08T12:20:17.066Z","repository":{"id":304711322,"uuid":"1018982263","full_name":"Psyhackological/shuttle-shellcon","owner":"Psyhackological","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-14T18:01:03.000Z","size":555,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-06T09:00:37.227Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Psyhackological.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-07-13T13:38:23.000Z","updated_at":"2025-07-14T18:01:07.000Z","dependencies_parsed_at":"2025-07-14T23:06:48.342Z","dependency_job_id":"efc71144-4741-4b3f-bbf6-1ddc508bb7c3","html_url":"https://github.com/Psyhackological/shuttle-shellcon","commit_stats":null,"previous_names":["psyhackological/shuttle-shellcon"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Psyhackological/shuttle-shellcon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Psyhackological%2Fshuttle-shellcon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Psyhackological%2Fshuttle-shellcon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Psyhackological%2Fshuttle-shellcon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Psyhackological%2Fshuttle-shellcon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Psyhackological","download_url":"https://codeload.github.com/Psyhackological/shuttle-shellcon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Psyhackological%2Fshuttle-shellcon/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269418729,"owners_count":24413665,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-08T02:00:09.200Z","response_time":72,"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":"2025-08-08T12:20:13.470Z","updated_at":"2025-08-08T12:20:17.051Z","avatar_url":"https://github.com/Psyhackological.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🦀 ShellCon Smart Aquarium – Full-Stack Challenge Guide 🐚\n\nWelcome to **ShellCon**, an onboarding playground where you will repair a broken _Smart Aquarium_ while learning Rust and Shuttle Cloud.  \nWhen you launch the dashboard, read the short *Scenario* banner at the top. It sets the story context and your mission before you start clicking around.\n\nThis **monorepo** contains everything:\n\n* Three Rust micro-services (`aqua-monitor`, `species-hub`, `aqua-brain`).\n* A React + Vite dashboard (`frontend/`).\n\nYour mission has **three phases**:\n\n1. **Get it running** – start every service \u0026 the UI locally; verify every dashboard button works.\n2. **Fix performance bugs** – complete four optimisation challenges inside the services.\n3. **Ship to the cloud \u0026 celebrate** – deploy with Shuttle.\n\n---\n## 📂 Repo layout\n\n```\nservices/\n  aqua-monitor/   # environmental sensors  (Challenges 1 \u0026 4)\n  species-hub/    # species DB             (Challenge 2)\n  aqua-brain/     # analytics engine       (Challenge 3)\nfrontend/         # React dashboard\n```\n\n---\n## 🛠️ Prerequisites\n\n* Rust 1.70+ \u0026 Cargo\n* Docker Desktop (Postgres for local Shuttle)\n* [Shuttle CLI](https://docs.shuttle.dev) (latest)\n* Node ≥16 \u0026 npm (or Yarn/Bun)\n\n### 🔑 One-time Shuttle setup\nInstall or update the Shuttle CLI, then **log in** before running any `shuttle run` or `shuttle deploy` commands.\n\n```bash\n# Install / update the CLI\ncurl -sSfL https://www.shuttle.dev/install | bash\n\n# Authenticate (opens a browser for sign-in or account creation)\nshuttle login\n```\n\n---\n## 🚀 Quick-start – **Local**\n\n### 1 · Launch the back-end services\n\nFirst off, clone this repository on your local machine:\n\n```bash\n# Clone the repository\ngit clone https://github.com/shuttle-hq/shuttle-shellcon.git\n# Change directory to the cloned repository\ncd shuttle-shellcon\n```\n\nRun the following commands in three separate terminals:\n```bash\n# Terminal 1\ncd shellcon-backend/services/aqua-monitor \u0026\u0026 shuttle run --port 8000\n# Terminal 2\ncd shellcon-backend/services/species-hub  \u0026\u0026 shuttle run --port 8001\n# Terminal 3\ncd shellcon-backend/services/aqua-brain  \u0026\u0026 shuttle run --port 8002\n```\nIf a port is busy: `lsof -ti :\u003cport\u003e | xargs kill -9` then retry. Alternatively, you can use the environment files to customize the ports as shown in the \"Environment files – local development\" section below.\n\n### 2 · Start the dashboard \u0026 confirm every API call locally\n\nOpen a new terminal and run the following commands at the root of the repository:\n```bash\ncd shellcon-frontend\nnpm install                 # first time only\nnpm run dev:localhost        # opens http://localhost:8080\n```\nThen open http://localhost:8080 in your browser and click \"Read Story Now\" to begin the ShellCon scenario.\n\nIn the **System Control Panel** click each button – no red errors should appear.\n\n| UI action | Request | Service |\n|-----------|---------|---------|\n| View all tanks | GET `/api/tanks` | aqua-monitor |\n| Fetch tank readings  | GET `/api/tanks/{id}/readings` | aqua-monitor |\n| Check sensor status  | GET `/api/sensors/status` | aqua-monitor |\n| List all species   | GET `/api/species` | species-hub |\n| Get species details | GET `/api/species/{id}` | species-hub |\n| Get feeding schedule | GET `/api/species/{id}/feeding-schedule` | species-hub |\n| View all tank analysis | GET `/api/analysis/tanks` | aqua-brain |\n| Tank health analysis | GET `/api/analysis/tanks/{id}` | aqua-brain |\n\n\u003e Challenges only affect **performance/validation** – the endpoint contracts above stay identical before \u0026 after solving them.\n\n---\n### 🖥️ Frontend dashboard tour\n\nThe dashboard is split into five panels:\n\n| Panel | What it shows |\n|-------|---------------|\n| **Scenario Banner** (top) | A short narrative that frames why you are fixing the aquarium – read it first! |\n| **System Control Panel** | Action buttons that call the REST endpoints listed above. |\n| **System Status** | Live backend connectivity and challenge status shown as **Normal** or **Error/Degraded**. |\n| **Optimization Challenges**| Cards describing each challenge with _Show Hint_, _Validate_, _View Solution_, and _Teach Me How It Works_ buttons. |\n\n---\n### ⚙️ Environment files – local development (`.env.localhost`)\n\n\u003e IMPORTANT: Use the following custom environment variables ONLY if ports 8000-8002 are already in use on your machine.\n\n`vite.config.ts` looks for three variables but falls back to the default localhost ports 8000-8002:\n\n```\nVITE_AQUA_MONITOR_URL    (default http://localhost:8000)\nVITE_SPECIES_HUB_URL     (default http://localhost:8001)\nVITE_AQUA_BRAIN_URL      (default http://localhost:8002)\n```\n\nYou override them by specifying other ports, as shown in the example below.\n\nSteps:\n1. `touch frontend/.env.localhost` and adjust if needed.\n2. Restart the dev server whenever you edit an `.env*` file.\n\n| File | When Vite picks it up | Typical use |\n|------|----------------------|-------------|\n| `.env.localhost` | `npm run dev:localhost` | Custom local ports or running services on another host. |\n\nExample **.env.localhost** (custom ports):\n```env\n# Local development backend services\nVITE_AQUA_MONITOR_URL=http://localhost:8020\nVITE_SPECIES_HUB_URL=http://localhost:8021\nVITE_AQUA_BRAIN_URL=http://localhost:8022\nVITE_API_BASE_URL=/api  # leave as /api unless you modify the proxy rules\n```\n---\n\n### 3 · Solve the optimisation challenges\n| # | Location | Topic |\n|---|----------|-------|\n| 1 | `aqua-monitor/src/challenges.rs::get_tank_readings` | Async I/O |\n| 2 | `species-hub/src/challenges.rs::get_species` | SQL optimisation |\n| 3 | `aqua-brain/src/challenges.rs::get_analysis_result` | String allocations |\n| 4 | `aqua-monitor/src/challenges.rs::get_sensor_status` | HTTP-client reuse |\n\nWorkflow per challenge:\n1. Read the lecture / hint.\n2. Edit the code inside the marked `// ⚠️ CHALLENGE` block.\n3. For some challenges, you’ll also need to modify `main.rs` to adjust relevant structures and functions so they can be imported in `challenges.rs`.\n4. Re-run **only** that service (`Ctrl-C`, then `shuttle run --port …`).\n5. Click **Validate** in the UI.\n\nComplete all four – the UI unlocks confetti! 🎉\n\n---\n## ☁️ Deploy \u0026 validate in the **cloud**\n\n1. For each service:\n   ```bash\n   cd services/\u003cservice\u003e\n   shuttle deploy\n   # choose “CREATE NEW”, project name = folder name (e.g aqua-brain)\n   ```\n2. Configure the **frontend for cloud**:\n   ```bash\n   # create the env file once (or edit it if it already exists)\n   touch frontend/.env.prod\n   ```\n   Open `frontend/.env.prod` and paste the URLs printed by each `shuttle deploy` command:\n\n   ```env\n   VITE_AQUA_MONITOR_URL=https://\u003caqua-monitor\u003e.shuttleapp.app\n   VITE_SPECIES_HUB_URL=https://\u003cspecies-hub\u003e.shuttleapp.app\n   VITE_AQUA_BRAIN_URL=https://\u003caqua-brain\u003e.shuttleapp.app\n   VITE_API_BASE_URL=/api\n   ```\n\n3. Restart the dashboard pointed at the cloud back-end:\n   ```bash\n   cd frontend\n   npm run dev:prod\n   ```\n   Re-validate each challenge card to confirm remote success.\n\n## ❓ FAQ\n\n**Q: Shuttle complains I’m not logged in.**  \nA: Run `shuttle login` once (see “One-time Shuttle setup”).\n\n**Q: A port is already in use.**  \nA: `lsof -ti :\u003cport\u003e | xargs kill -9` frees it before re-running.\n\n**Q: The UI shows red banners / fetch errors.**  \nA: Check that each backend terminal shows `Listening on 0.0.0.0:PORT` and that your `.env*` URLs match.\n\n**Q: Validation keeps failing even after I fixed the code.**  \nA: Restart the corresponding service, then click *Validate* again; the validator inspects live code. When you validate a function, you can see more details about the validation results in shuttle logs (`shuttle logs --latest`). For example, if you validate the `get_tank_readings` function, you can see the following validation results in the logs:\n```text\nChallenge validation check results request_id=f576a0f6-059b-464c-bddb-0205748e1418 uses_async_io=true no_blocking_operations=true has_proper_tracing=true\n```\n\n**Q: How do I reset a service database?**  \nA: Find the Docker container for the desired PostgreSQL database (there will be two databases serving ShellCon microservices), and delete it using `docker rm -f \u003ccontainer_name\u003e`. Then restart the service using `shuttle run --port \u003cport\u003e`.\n\n---\n## 🩹 Troubleshooting cheat-sheet\n\n* `cargo check` + `cargo fmt` before running.\n* Runtime errors: `shuttle logs --latest`.\n* Validation fails?  Ensure the UI points to the right environment (localhost vs cloud).\n* Port in use: `lsof -ti :\u003cport\u003e | xargs kill -9`.\n\n---\n## 🎓 What you’ll learn\n\n* Async vs blocking I/O in Rust\n* Writing efficient SQL with SQLx \u0026 Postgres\n* Minimising heap allocations (Strings \u0026 Vec)\n* Resource pooling \u0026 shared state with Axum\n* Shuttle local dev → cloud deployment workflow\n\nGood luck, Rustacean – the aquarium (and Ferris the crab 🦀) is counting on you!\n\n\u003e **Note:** Any contribution to the project is welcome! Please open an issue or a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsyhackological%2Fshuttle-shellcon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpsyhackological%2Fshuttle-shellcon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsyhackological%2Fshuttle-shellcon/lists"}