{"id":49765812,"url":"https://github.com/yezz123/ai-template","last_synced_at":"2026-05-11T10:46:40.741Z","repository":{"id":44742463,"uuid":"366633671","full_name":"yezz123/ai-template","owner":"yezz123","description":"Multi-tenant SaaS boilerplate built on FastAPI \u0026 Authx :sparkles:","archived":false,"fork":false,"pushed_at":"2026-05-01T17:57:16.000Z","size":734,"stargazers_count":244,"open_issues_count":1,"forks_count":40,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-05-01T19:24:20.951Z","etag":null,"topics":["ai","asyncio","authx","fastapi","nextjs","python","rest-api","sqlalchemy","swagger-ui","uvicorn"],"latest_commit_sha":null,"homepage":"","language":"Python","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/yezz123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"docs/CODE_OF_CONDUCT.md","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},"funding":{"custom":["https://paypal.me/yassertahiri"]}},"created_at":"2021-05-12T07:43:32.000Z","updated_at":"2026-05-01T17:57:20.000Z","dependencies_parsed_at":"2024-01-03T02:30:08.065Z","dependency_job_id":"a8328fb7-93f2-4591-9319-c4ef245e707f","html_url":"https://github.com/yezz123/ai-template","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/yezz123/ai-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fai-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fai-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fai-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fai-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yezz123","download_url":"https://codeload.github.com/yezz123/ai-template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yezz123%2Fai-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32891955,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"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":["ai","asyncio","authx","fastapi","nextjs","python","rest-api","sqlalchemy","swagger-ui","uvicorn"],"created_at":"2026-05-11T10:46:39.989Z","updated_at":"2026-05-11T10:46:40.735Z","avatar_url":"https://github.com/yezz123.png","language":"Python","funding_links":["https://paypal.me/yassertahiri"],"categories":[],"sub_categories":[],"readme":"# AI Template\n\n\u003e Multi-tenant SaaS boilerplate built on FastAPI + [authx](https://github.com/yezz123/authx) + Next.js. Every feature toggleable via env vars; ship a production-ready SaaS in a weekend.\n\n[![Backend](https://github.com/yezz123/ai-template/actions/workflows/backend.yaml/badge.svg)](https://github.com/yezz123/ai-template/actions/workflows/backend.yaml)\n[![Frontend](https://github.com/yezz123/ai-template/actions/workflows/frontend.yaml/badge.svg)](https://github.com/yezz123/ai-template/actions/workflows/frontend.yaml)\n[![Admin](https://github.com/yezz123/ai-template/actions/workflows/admin.yaml/badge.svg)](https://github.com/yezz123/ai-template/actions/workflows/admin.yaml)\n\n## What you get\n\n- **Organizations / Workspaces** with per-org data isolation (every tenant row carries `org_id`).\n- **Roles**: Owner / Admin / Member, mapped to authx **scopes** with wildcard support (`org:members:*`).\n- **JWT scoped to org** \u0026mdash; switch orgs and the access token is re-issued with the new `org_id` and computed scopes.\n- **API keys per organization** with scoped permissions, validated via `X-API-Key`.\n- **Email invitations** \u0026mdash; or token-link only when email delivery is disabled.\n- Optional, all gated by `FEATURE_*` env vars: OAuth (Google/GitHub), magic-link, real email delivery (Resend/SMTP), Stripe billing, Pydantic AI + LLM Gateway (chat + demo agents), Logfire observability, audit log, rate limiting.\n\n## Repository layout\n\n```\nai-template/\n├── backend/         FastAPI + authx + SQLAlchemy + Alembic (uv-managed)\n├── frontend/        Next.js 16 tenant-facing app (Tailwind v4, Framer Motion, Zod)\n├── admin/           Next.js 16 super-admin portal\n├── infra/           docker-compose + postgres init\n├── .env.example     every FEATURE_* and secret in one place\n└── Makefile         `make dev`, `make test`, `make migrate`, ...\n```\n\n## Stack\n\n| Layer        | Tech                                                                                                                        |\n| ------------ | --------------------------------------------------------------------------------------------------------------------------- |\n| Backend      | FastAPI, Pydantic v2, [authx](https://pypi.org/project/authx/) 1.6.0, SQLAlchemy 2 async, Alembic, Postgres 17, Redis 7, uv |\n| Frontend     | Next.js 16, React 19, Tailwind v4, Framer Motion, Zod, bun                                                                  |\n| Admin Portal | Next.js 16, React 19, Tailwind v4, Framer Motion, Zod, bun                                                                  |\n| Optional     | Pydantic AI, LLM Gateway, Pydantic Logfire, Resend, Stripe, Authlib                                                         |\n\n## Quick start\n\nPrereqs: **uv** \u0026ge; 0.5, **bun** \u0026ge; 1.3, **Docker**.\n\n### Option A: run everything with Docker (recommended)\n\n```bash\ngit clone https://github.com/yezz123/ai-template \u0026\u0026 cd ai-template\ncp .env.example .env\n\nmake stack-build\nmake stack-up\nmake stack-ps\n```\n\n- Backend: `http://localhost:8000` (OpenAPI UI: `http://localhost:8000/docs`)\n- Frontend: `http://localhost:3000`\n- Admin: `http://localhost:3001`\n- Mailpit: `http://localhost:8025`\n\n```bash\nmake stack-logs\n```\n\n### Option B: run infra in Docker + apps locally (fast inner loop)\n\n```bash\ngit clone https://github.com/yezz123/ai-template \u0026\u0026 cd ai-template\ncp .env.example .env\n\nmake bootstrap          # uv sync + bun install\nmake up                 # postgres + redis + mailpit\nmake migrate            # alembic upgrade head\n\n# In three separate terminals:\nmake dev-backend        # http://localhost:8000  (FastAPI + /docs)\nmake dev-frontend       # http://localhost:3000  (tenant app)\nmake dev-admin          # http://localhost:3001  (super-admin)\n```\n\n## Feature flags\n\nEvery optional module is gated by an env var. Disabled features incur **zero**\nruntime cost \u0026mdash; their routers are never registered, their dependencies never\nimported.\n\n| Flag                     | Default | Module                         |\n| ------------------------ | ------- | ------------------------------ |\n| `FEATURE_API_KEYS`       | `true`  | API keys per org (`X-API-Key`) |\n| `FEATURE_AUDIT_LOG`      | `true`  | Audit log of mutations         |\n| `FEATURE_RATE_LIMITING`  | `true`  | authx `RateLimiter` + Redis    |\n| `FEATURE_OAUTH`          | `false` | Google + GitHub via Authlib    |\n| `FEATURE_MAGIC_LINK`     | `false` | Passwordless                   |\n| `FEATURE_EMAIL_DELIVERY` | `false` | Resend / SMTP                  |\n| `FEATURE_AI_CHAT`        | `false` | Pydantic AI + LLM Gateway      |\n| `FEATURE_LOGFIRE`        | `false` | Pydantic Logfire tracing       |\n| `FEATURE_STRIPE`         | `false` | Per-org subscriptions          |\n\nOptional Python deps live behind `pyproject.toml` extras:\n\n```bash\nuv sync --extra ai --extra stripe       # only what you need\nuv sync --extra all                     # everything\n```\n\nFrontend and Admin feature visibility is gated by `NEXT_PUBLIC_FEATURE_*` vars\nwhich are baked into the Next.js bundle at build time (see `.env.example`).\n\n## Multi-tenancy model\n\n- Shared database, shared schema. Every tenant row has `org_id UUID NOT NULL` with composite indexes.\n- The active org lives in the JWT (`data.org_id` + `data.role` + `scopes`).\n- `current_org` FastAPI dep extracts the org from the token and every repository function takes it as a required argument.\n- `POST /orgs/{slug}/switch` re-issues the token pair with new claims.\n\n## Roles \u0026rarr; scopes\n\n```python\nROLE_SCOPES = {\n    Role.OWNER:  [\"org:*\"],\n    Role.ADMIN:  [\"org:members:*\", \"org:apikeys:*\", \"org:audit:read\", \"org:billing:read\", \"org:ai:*\"],\n    Role.MEMBER: [\"org:read\", \"org:ai:use\"],\n}\n```\n\nRoutes use `auth.scopes_required(...)` \u0026mdash; wildcards (`\"org:*\"`) match\neverything underneath.\n\n## Development\n\nSee per-app READMEs:\n\n- [backend/README.md](backend/README.md)\n- [frontend/README.md](frontend/README.md)\n- [admin/README.md](admin/README.md)\n\n```bash\nmake test               # all suites\nmake lint               # ruff + next lint\nmake typecheck-backend  # mypy\n```\n\n## Troubleshooting\n\n- **CSRF 401s on POST/PUT/PATCH/DELETE**: auth is cookie-based and expects `X-CSRF-TOKEN`. The Next.js clients automatically mirror the CSRF cookie into that header; if you’re rolling your own client, do the same.\n- **Migrations failing inside Docker**: `migrate` runs before `backend`. Rebuild images after changing deps: `make stack-build \u0026\u0026 make stack-up`.\n- **OAuth not working locally**: set `FEATURE_OAUTH=true` and add provider keys + callback URLs. Make sure `APP_BASE_URL`, `FRONTEND_BASE_URL`, and `ADMIN_BASE_URL` match where you’re running.\n- **“Feature is missing in UI”**: ensure both `FEATURE_*` (backend) and `NEXT_PUBLIC_FEATURE_*` (frontend/admin) are enabled, and rebuild Next.js if using Docker (public env is baked at build time).\n\n## License\n\nMIT \u0026mdash; see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezz123%2Fai-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyezz123%2Fai-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyezz123%2Fai-template/lists"}