{"id":49726432,"url":"https://github.com/hazeliscoding/bloomwatch","last_synced_at":"2026-05-09T04:31:05.920Z","repository":{"id":344212321,"uuid":"1180930550","full_name":"hazeliscoding/bloomwatch","owner":"hazeliscoding","description":"A shared anime tracking platform for pairs and small groups.","archived":false,"fork":false,"pushed_at":"2026-04-10T21:21:40.000Z","size":1146,"stargazers_count":0,"open_issues_count":25,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-10T21:33:09.536Z","etag":null,"topics":["angular","anime-tracker","dotnet","scalar"],"latest_commit_sha":null,"homepage":"","language":"C#","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/hazeliscoding.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":"2026-03-13T15:07:16.000Z","updated_at":"2026-04-10T21:21:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hazeliscoding/bloomwatch","commit_stats":null,"previous_names":["hazeliscoding/bloomwatch"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hazeliscoding/bloomwatch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazeliscoding%2Fbloomwatch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazeliscoding%2Fbloomwatch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazeliscoding%2Fbloomwatch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazeliscoding%2Fbloomwatch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hazeliscoding","download_url":"https://codeload.github.com/hazeliscoding/bloomwatch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazeliscoding%2Fbloomwatch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32807141,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"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":["angular","anime-tracker","dotnet","scalar"],"created_at":"2026-05-09T04:31:05.160Z","updated_at":"2026-05-09T04:31:05.913Z","avatar_url":"https://github.com/hazeliscoding.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🌸 BloomWatch\n\n\u003e A shared anime tracking platform for pairs and small groups.\n\nBloomWatch lets friends maintain a joint backlog, track watch progress, leave separate ratings, and discover how compatible their taste really is — no more spreadsheets or Discord threads!\n\n## ✨ Features\n\n- **Watch Spaces** — Create shared spaces for you and your watch partner(s)\n- **AniList Integration** — Search and add anime directly from AniList, with cached metadata\n- **Individual Progress** — Everyone tracks their own episodes and status independently\n- **Ratings \u0026 Reviews** — Personal 0.5–10 ratings with optional notes\n- **Compatibility Analytics** — See how your ratings align, find your biggest disagreements, and get random backlog picks\n- **Kawaii/Y2K Design** — A playful pastel design system with gel effects, light/dark themes, and custom components\n\n## 🛠 Tech Stack\n\n| Layer | Tech |\n|-------|------|\n| **Backend** | .NET 10 · ASP.NET Core Minimal APIs · PostgreSQL · EF Core 9 · JWT auth |\n| **Frontend** | Angular 21 · SCSS design tokens · Vitest |\n| **Architecture** | DDD-inspired modular monolith (5 modules, one DB schema each) |\n| **Testing** | 700+ automated tests (180 xUnit backend + 527 Vitest frontend) |\n| **API Docs** | OpenAPI + [Scalar](https://scalar.com/) interactive explorer at `/scalar/v1` |\n\n## 🚀 Quick Start\n\n**Prerequisites:** [.NET 10 SDK](https://dotnet.microsoft.com/download) · [Node.js 18+](https://nodejs.org/) · PostgreSQL · [Docker](https://www.docker.com/) (optional, for local email)\n\n```bash\n# 1. Clone and restore\ngit clone \u003crepo-url\u003e \u0026\u0026 cd bloomwatch\ndotnet restore\n\n# 2. Configure the database (override if your setup differs)\n#    Default: Host=localhost;Database=bloomwatch;Username=postgres;Password=postgres\nexport ConnectionStrings__DefaultConnection=\"Host=localhost;Database=bloomwatch;Username=youruser;Password=yourpass\"\n\n# 3. (Optional) Start Mailpit to capture invitation emails locally\ndocker run -d -p 1025:1025 -p 8025:8025 axllent/mailpit\n# → SMTP on localhost:1025  ·  Web UI at http://localhost:8025\n\n# 4. Apply migrations and start the API\n./scripts/apply-migrations.sh\ndotnet run --project src/BloomWatch.Api\n# → http://localhost:5192  (API docs at /scalar/v1)\n\n# 5. Start the frontend\ncd src/BloomWatch.UI \u0026\u0026 npm install \u0026\u0026 npm start\n# → http://localhost:4200\n```\n\n## 🗄️ Database Scripts\n\nUse the helper scripts in [scripts/](scripts/) for common EF Core database tasks:\n\n```bash\n# Apply all module migrations\n./scripts/apply-migrations.sh\n\n# Create a migration for one module\n./scripts/add-migration.sh \u003cmodule\u003e \u003cMigrationName\u003e\n\n# Drop the database (with confirmation)\n./scripts/drop-database.sh\n\n# Drop the database without confirmation (automation/CI)\n./scripts/drop-database.sh --force\n```\n\nSupported modules for `add-migration.sh`:\n\n- `identity`\n- `watchspaces`\n- `anilistsync`\n- `animetracking`\n\nExample:\n\n```bash\n./scripts/add-migration.sh identity AddRefreshTokenTable\n```\n\n## 🧪 Running Tests\n\n```bash\ndotnet test                          # All backend tests\ncd src/BloomWatch.UI \u0026\u0026 npm test     # Frontend tests\n```\n\nBackend integration tests use in-memory SQLite via `WebApplicationFactory` — no running database needed.\n\n## � Interactive API Docs (Scalar)\n\nWith the API running (`dotnet run --project src/BloomWatch.Api`), open **[http://localhost:5192/scalar/v1](http://localhost:5192/scalar/v1)** in your browser to access the Scalar API explorer.\n\nScalar provides:\n\n- **Browse all 30 endpoints** grouped by module (Identity, WatchSpaces, AniList, AnimeTracking, Analytics, Home)\n- **Try requests live** — fill in parameters, set headers, and execute calls against your local API\n- **Authenticate** — click the 🔒 lock icon, paste a JWT obtained from `POST /auth/login`, and all subsequent requests include the `Authorization: Bearer` header automatically\n- **View request/response schemas** — expand any endpoint to see the full JSON shape, required fields, and status codes\n\n\u003e **Tip:** Register a user via `POST /auth/register`, then log in via `POST /auth/login` to get a token. Paste it into Scalar's auth dialog and you can explore every protected endpoint interactively.\n\nThe raw OpenAPI JSON spec is also available at [`/openapi/v1.json`](http://localhost:5192/openapi/v1.json) for importing into other tools (Postman, Insomnia, etc.).\n\n## 📁 Project Structure\n\n```\nsrc/\n├── BloomWatch.Api/              # HTTP host, endpoint registration, middleware\n├── BloomWatch.SharedKernel/     # Cross-cutting abstractions\n├── BloomWatch.UI/               # Angular frontend (features, shared UI, design system)\n└── Modules/\n    ├── Identity/                # Registration, login, JWT, user profiles\n    ├── WatchSpaces/             # Watch space CRUD, invitations, membership\n    ├── AniListSync/             # AniList GraphQL proxy with persistent caching\n    ├── AnimeTracking/           # Anime lifecycle, progress, ratings per watch space\n    └── Analytics/               # Compatibility scores, rating gaps, shared stats\n\ntests/                           # Unit + integration tests per module (10 xUnit projects)\ndocs/                            # Architecture, UI/UX doctrine, user stories, wireframes\nopenspec/                        # Spec-driven change tracking (see below)\n```\n\nEach module follows a consistent DDD layering: **Domain → Application → Infrastructure → Contracts**.\n\n## 🧩 Modules\n\n| Module | Schema | Responsibility |\n|--------|--------|---------------|\n| **Identity** | `identity` | User registration, login, JWT authentication, and profile management |\n| **WatchSpaces** | `watch_spaces` | Shared space lifecycle, invitations, membership, and ownership transfer |\n| **AniListSync** | `anilist_sync` | AniList GraphQL proxy with persistent `media_cache` table (24-hour freshness) and in-memory search cache (5-minute TTL) |\n| **AnimeTracking** | `anime_tracking` | Per-space anime lifecycle, shared group status, individual participant progress/ratings |\n| **Analytics** | *(read-only)* | Compatibility scores, rating gap analysis, shared stats, dashboard summaries, and random backlog picks |\n\nModules communicate through **read-only cross-module `DbContext`s** — never by calling another module's services or repositories directly. This preserves bounded context isolation while sharing a single database.\n\n## 🎨 Design System\n\nThe frontend ships a custom `bloom-*` component library with a kawaii/Y2K aesthetic (Quicksand + Nunito typefaces, pastel palette, gel effects). Components include buttons, cards, inputs, badges, avatars, modals, a compatibility ring, and a backlog picker.\n\nDesign tokens, animations, and utilities live in `src/BloomWatch.UI/src/app/shared/styles/`. See [`docs/ui-ux-doctrine.md`](docs/ui-ux-doctrine.md) for the full design system reference.\n\n## 📐 Architecture\n\nThis is a **modular monolith** — five domain modules sharing a single deployment but separated by schema, bounded context, and clean cross-module contracts.\n\nSee [`docs/architecture.md`](docs/architecture.md) for the full design doc covering module boundaries, database strategy, and planned feature phases.\n\n## 📝 OpenSpec Workflow\n\nBloomWatch uses a spec-driven change management workflow. Every feature is planned as a proposal with a design doc, feature specs, and a task checklist before implementation begins.\n\n```\npropose → apply → archive\n```\n\nCompleted changes are archived in `openspec/changes/archive/`. Feature specs live in `openspec/specs/`.\n\n## 📜 License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhazeliscoding%2Fbloomwatch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhazeliscoding%2Fbloomwatch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhazeliscoding%2Fbloomwatch/lists"}