{"id":50683172,"url":"https://github.com/up2dul/siaplulus","last_synced_at":"2026-06-08T20:32:36.550Z","repository":{"id":350159149,"uuid":"1205403824","full_name":"up2dul/siaplulus","owner":"up2dul","description":"[WIP] AI-powered Career Assistant","archived":false,"fork":false,"pushed_at":"2026-04-09T05:44:47.000Z","size":153,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-09T06:26:58.853Z","etag":null,"topics":["alembic","docker","fastapi","monorepo","moonrepo","python","react","scalar","shadcn-ui","tailwindcss","tanstack-router","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/up2dul.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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-08T23:52:13.000Z","updated_at":"2026-04-09T05:44:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/up2dul/siaplulus","commit_stats":null,"previous_names":["up2dul/siaplulus"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/up2dul/siaplulus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/up2dul%2Fsiaplulus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/up2dul%2Fsiaplulus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/up2dul%2Fsiaplulus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/up2dul%2Fsiaplulus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/up2dul","download_url":"https://codeload.github.com/up2dul/siaplulus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/up2dul%2Fsiaplulus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34080027,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"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":["alembic","docker","fastapi","monorepo","moonrepo","python","react","scalar","shadcn-ui","tailwindcss","tanstack-router","typescript"],"created_at":"2026-06-08T20:32:35.581Z","updated_at":"2026-06-08T20:32:36.519Z","avatar_url":"https://github.com/up2dul.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Siaplulus\n\n\u003e Siaplulus aims to become a **personal AI career assistant** that helps job seekers understand their competitiveness in the job market and prepare effectively for job applications.\n\n## Tech Stack\n\n**Frontend** (`apps/web`)\n\n- [React 19](https://react.dev) + [TypeScript](https://www.typescriptlang.org)\n- [Vite](https://vitejs.dev) — build tool\n- [Tailwind CSS v4](https://tailwindcss.com) — styling\n- [shadcn/ui](https://ui.shadcn.com) — component library\n- [TanStack](https://tanstack.com) — Router, Query, Table\n\n**Backend** (`apps/api`)\n\n- [FastAPI](https://fastapi.tiangolo.com) — API framework\n- [Alembic](https://alembic.sqlalchemy.org) — database migrations\n- [Celery](https://docs.celeryq.dev) + Redis — background task queue\n- [Ruff](https://docs.astral.sh/ruff) — linter \u0026 formatter\n- [Loguru](https://loguru.readthedocs.io) — logging\n- [Scalar](https://scalar.com) — API docs\n\n**Shared** (`packages/core`)\n\n- [openapi-typescript](https://openapi-ts.dev) — generates TypeScript types from FastAPI's OpenAPI schema\n- [openapi-fetch](https://openapi-ts.dev/openapi-fetch/) — fully typed API client\n\n**Monorepo \u0026 Tooling**\n\n- [Moon](https://moonrepo.dev) — task runner \u0026 monorepo orchestration\n- [Proto](https://moonrepo.dev/proto) — toolchain version management\n- [pnpm](https://pnpm.io) — JavaScript package manager\n- [uv](https://docs.astral.sh/uv) — Python package manager\n- [Biome](https://biomejs.dev) — JavaScript/TypeScript linter \u0026 formatter (root-level, shared across all JS/TS projects)\n- [Lefthook](https://lefthook.dev) — Git hooks\n- [commitlint](https://commitlint.js.org) — commit message linting\n\n## Prerequisites\n\nInstall [Proto](https://moonrepo.dev/docs/proto/install) — it manages all other tool versions automatically:\n\n```bash\ncurl -fsSL https://moonrepo.dev/install/proto.sh | bash\n```\n\nProto will handle Node.js, pnpm, Python, and Moon based on `.prototools`.\n\n## Getting Started\n\n### Clone the repo\n\n```bash\ngit clone https://github.com/up2dul/siaplulus.git\n\n# Or if you have SSH access\ngit clone git@github.com:up2dul/siaplulus.git\n```\n\n### Move into the project directory\n\n```bash\ncd siaplulus\n```\n\n### Install dependencies and set up Git hooks\n\n```bash\n# Install JS dependencies\npnpm install\n\n# Install Python dependencies\nuv sync --project apps/api\n```\n\n## Running the Project\n\n```bash\n# Start the frontend dev server\nmoon run web:dev\n\n# Start the backend dev server\nmoon run api:dev\n\n# Start both simultaneously\nmoon run web:dev api:dev\n\n# Start the Celery worker\nmoon run api:worker\n```\n\nThe frontend runs at `http://localhost:3000` and the backend at `http://localhost:8000`.  \n\nAPI docs are available at `http://localhost:8000/scalar`.\n\n## Project Structure\n\n```\nmy-project/\n├── .moon/\n│   ├── workspace.yml         # Project locations \u0026 Moon config\n│   └── toolchains.yml        # Language \u0026 tool versions\n├── apps/\n│   ├── web/                  # React frontend\n│   │   ├── src/\n│   │   │   ├── modules/      # Feature modules (components + hooks)\n│   │   │   ├── routes/       # TanStack file-based routes\n│   │   │   └── lib/\n│   │   │       └── api.ts    # Singleton API client (from @repo/core)\n│   │   └── moon.yml\n│   └── api/                  # FastAPI backend\n│       ├── app/\n│       │   ├── api/          # Routes \u0026 serializers (Pydantic schemas)\n│       │   ├── modules/      # Business logic (services)\n│       │   ├── models/       # SQLAlchemy models\n│       │   └── core/         # Settings, logging, celery\n│       ├── alembic/          # Database migrations\n│       └── moon.yml\n├── packages/\n│   └── core/                 # Shared typed API client\n│       └── src/\n│           ├── api/          # Feature API methods\n│           ├── client.ts     # createApi() factory\n│           ├── schema.d.ts   # Auto-generated from /openapi.json (gitignored)\n│           └── index.ts\n├── .prototools               # Pinned tool versions\n├── biome.json                # Shared Biome config (root-level)\n├── commitlint.config.ts      # Commit message rules\n├── docker-compose.yml        # Local/staging services\n├── docker-compose.prod.yml   # Production overrides\n├── lefthook.yml              # Git hook definitions\n├── package.json\n└── pnpm-workspace.yaml\n```\n\n## Common Tasks\n\n### Frontend\n\n```bash\nmoon run web:dev          # Dev server\nmoon run web:build        # Production build\nmoon run web:lint         # Lint with Biome\nmoon run web:format       # Format with Biome\nmoon run web:check        # Lint + format + fix with Biome\nmoon run web:typecheck    # TypeScript type checking\n```\n\n### Backend\n\n```bash\nmoon run api:dev          # Dev server\nmoon run api:lint         # Lint with Ruff\nmoon run api:format       # Format with Ruff\nmoon run api:migrate      # Run Alembic migrations\nmoon run api:worker       # Start Celery worker\n```\n\n### Shared package\n\n```bash\nmoon run core:generate    # Regenerate TypeScript types from OpenAPI schema\nmoon run core:typecheck   # Type check packages/core\n```\n\n### Whole monorepo\n\n```bash\nmoon run :lint            # Lint all projects\nmoon run :format          # Format all projects\nmoon run :check           # Check all JS/TS projects\n```\n\n## Type-Safe API\n\nTypeScript types in `packages/core` are auto-generated from FastAPI's OpenAPI schema. Run this whenever you change a Pydantic schema:\n\n```bash\n# API must be running\nmoon run core:generate\n```\n\nThe frontend never calls `fetch` directly — it uses the typed API client:\n\n```ts\n// apps/web/src/lib/api.ts — instantiated once\nimport { createApiWithModules } from \"@repo/core\";\n\nexport const api = createApiWithModules({\n  baseUrl: import.meta.env.VITE_API_URL || \"http://localhost:8000\",\n  onTokenRefreshFailed: () =\u003e {\n    window.location.href = \"/login\";\n  },\n});\n\n// Usage in a hook\nconst { data } = useQuery({\n  queryKey: [\"users\", \"me\"],\n  queryFn: () =\u003e api.users.me(),\n});\n// data is fully typed as UserResponse — no 'any'\n```\n\n## Database Migrations\n\n```bash\n# Apply all pending migrations\nmoon run api:migrate\n\n# Create a new migration (from apps/api)\ncd apps/api\nuv run alembic revision --autogenerate -m \"add users table\"\n```\n\nAlways import new models in `alembic/env.py` for autogenerate to detect them.\n\n## Environment Variables\n\n| Variable            | Location        | Description                      |\n| ------------------- | --------------- | -------------------------------- |\n| `VITE_API_URL`      | `apps/web/.env` | Backend API base URL             |\n| `DATABASE_URL`      | `apps/api/.env` | PostgreSQL connection string     |\n| `REDIS_URL`         | `apps/api/.env` | Redis connection string          |\n| `SECRET_KEY`        | `apps/api/.env` | Application secret key           |\n| `POSTGRES_USER`     | `apps/api/.env` | DB user (used by Docker Compose) |\n| `POSTGRES_PASSWORD` | `apps/api/.env` | DB password                      |\n| `POSTGRES_DB`       | `apps/api/.env` | DB name                          |\n\n## Deployment\n\nThe project deploys via Docker Compose to a VPS. Traffic is routed through Nginx:\n\n```\nBrowser → Nginx (port 80/443)\n            ├── api.domain.com  →  FastAPI (port 8000)\n            └── domain.com      →  React/Nginx (port 80)\n```\n\n```bash\n# Build and run all services\ndocker compose -f docker-compose.yml up -d\n```\n\n## Git Workflow\n\nThis project enforces [Conventional Commits](https://www.conventionalcommits.org):\n\n```\n\u003ctype\u003e(\u003coptional scope\u003e): \u003cdescription\u003e\n```\n\nValid types: `feat` `fix` `docs` `style` `refactor` `perf` `test` `chore` `revert` `ci`\n\n```bash\ngit commit -m \"feat(web/auth): add JWT refresh token\"\ngit commit -m \"fix(api/users): resolve null pointer in user endpoint\"\ngit commit -m \"chore: bump dependencies\"\n```\n\nThe `pre-commit` hook automatically runs Biome (JS/TS) and Ruff (Python) on staged files. The `commit-msg` hook validates the commit message format.\n\n## Boilerplate Inspirations\n\n- [indrazm/moonrepo-kickstart](https://github.com/indrazm/moonrepo-kickstart)\n- [zero-one-group/monorepo](https://github.com/zero-one-group/monorepo)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fup2dul%2Fsiaplulus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fup2dul%2Fsiaplulus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fup2dul%2Fsiaplulus/lists"}