{"id":28606004,"url":"https://github.com/bigrivi/black-panther","last_synced_at":"2026-04-12T02:32:45.518Z","repository":{"id":286819413,"uuid":"961404386","full_name":"bigrivi/black-panther","owner":"bigrivi","description":"Full stack web application scaffold,Using FastAPI,BetterCRUD,Refine and more. ","archived":false,"fork":false,"pushed_at":"2025-07-30T00:51:43.000Z","size":5272,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-30T02:56:40.001Z","etag":null,"topics":["admin-ui","bettercrud","fastapi","fullstack-development","low-code","material-ui","python","react","refine"],"latest_commit_sha":null,"homepage":"","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/bigrivi.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-04-06T13:02:13.000Z","updated_at":"2025-07-30T00:51:46.000Z","dependencies_parsed_at":"2025-04-28T01:23:53.270Z","dependency_job_id":"8376d52c-259e-47f0-993c-19cadb08bd17","html_url":"https://github.com/bigrivi/black-panther","commit_stats":null,"previous_names":["bigrivi/photinia","bigrivi/black-panther"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/bigrivi/black-panther","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigrivi%2Fblack-panther","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigrivi%2Fblack-panther/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigrivi%2Fblack-panther/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigrivi%2Fblack-panther/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bigrivi","download_url":"https://codeload.github.com/bigrivi/black-panther/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigrivi%2Fblack-panther/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31702579,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T21:17:31.016Z","status":"online","status_checked_at":"2026-04-12T02:00:06.763Z","response_time":58,"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":["admin-ui","bettercrud","fastapi","fullstack-development","low-code","material-ui","python","react","refine"],"created_at":"2025-06-11T19:12:18.089Z","updated_at":"2026-04-12T02:32:45.506Z","avatar_url":"https://github.com/bigrivi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/bigrivi/black-panther\"\u003e\n  \u003cimg src=\"resources/black-panter.png\" alt=\"BlackPanther is a Full stack web application scaffold,Using FastAPI,BetterCRUD,Refine and more.\" width=\"300\" height=\"auto\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\" markdown=1\u003e\n  \u003ci\u003eFull-stack Web application scaffolding,low-code builder, the perfect combination of \u003cb\u003eRefine\u003c/b\u003e and \u003cb\u003eBetterCRUD\u003c/b\u003e\u003c/i\u003e\n\u003c/p\u003e\n\u003chr\u003e\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"resources/combination.svg\" width=\"40%\" height=\"auto\"\u003e\n\u003c/p\u003e\n\n**BlackPanther** is a complete full-stack web application scaffolding that uses FastAPI, BetterCRUD, Refine, and more.\nHe has defined a set of good front-end and back-end development best practices to quickly develop products such as CRM, CMS, Admin Dashboard and other different types of management systems\n\nAt the same time, **BlackPanther** is also a low-code builder that provides a series of low-code components and solutions\n\nI like [Refine](https://refine.dev/) very much, I think it's a good solution for the front-end to produce products quickly, and I have always hoped that Refine can be combined with [BetterCRUD](https://github.com/bigrivi/better_crud) to generate strong productivity, which is also the original intention of this project\n\n⭐ If you find BlackPanther useful, please consider giving us a star on GitHub! Your support helps us continue to innovate and deliver exciting features.\n\n## Technology Stack\n\n- ⚡ [**FastAPI**](https://fastapi.tiangolo.com) for the Python backend API.\n    - ✒️ [BetterCRUD](https://github.com/bigrivi/better_crud) Quickly implement CRUD functions\n    - 🧰 [SQLModel](https://sqlmodel.tiangolo.com) for the Python SQL database interactions (ORM).\n    - 🔍 [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management.\n- 🚀 [React](https://react.dev) for the frontend.\n    - 🐱 Using TypeScript, hooks, Vite, and other parts of a modern frontend stack.\n    - ☣️ [Refine](https://refine.dev/) for the frontend CRUD pages.\n    - 🔷 [Material UI](material-ui.com) for the frontend ui components.\n    - 🐩 [Material React Table](https://www.material-react-table.com/) for the list page tables\n    - 💅 [react-hook-form-mui](https://github.com/dohomi/react-hook-form-mui) for the create/edit page forms\n\n## All features\n- 🎁 **Very nice front-end UI interface**:Thanks to the appearance of Material UI\n- 🔑 **JWT** (JSON Web Token) authentication.\n- 🔒 **Secure** password hashing by default.\n- 🐼 **Login Authorization**\n- 🐎 **Role-Based Access Control**:Powerful role-based asset action control\n- 🐥 **Multi-language support**\n- 🎓 **Dark mode support**\n- 🎉 **Built-in Module**\n  - 💿 **User Management**\n  - 🎇 **Role Management**\n  - 🎃 **Position Management**\n  - 🔦 **Department Management**\n  - 📲 **Resource Management**\n  - 🔈 **Policy**\n  - 🏠 **Enum Management**\n  - 🌠 **Parameter setting**\n  - 🎁 **Dynamic module**\n\n\u003chr\u003e\n\n### Login\n![Login](resources/login.png)\n\n### Policy\n![Policy List](resources/policy-list.png)\n![Policy Grid](resources/policy-grid.png)\n![Policy Save](resources/policy-save.png)\n\n### User\n1. List\n![User List](resources/user-list.png)\n2. Create\n![User Create](resources/user-create.png)\n\n### Role\n1. List\n![Role List](resources/role-list.png)\n2. Create\n![Role Create](resources/role-create.png)\n\n### Resource\n1. List\n![Resource List](resources/resource-list.png)\n\n2. Create\n![Resource Create](resources/resource-create.png)\n\n\n### Department\n1. List\n![Department List](resources/department-list.png)\n\n2. Create\n![Department Create](resources/department-create.png)\n\n### Enum\n1. List\n![Enum List](resources/enum-list.png)\n\n2. Edit\n![Enum Edit](resources/enum-edit.png)\n\n#### Sidebar mini mode\n![Sidebar](resources/sidebar-mini.png)\n\n#### Chinese Simplified switch\n![Chinese Simplified switch](resources/zh-cn-switch.png)\n\n#### Dark mode\n![Dark mode](resources/dark-mode.png)\n\n### Dynamic module support\n\nCompared with other features, this is a dessert-level feature 😃 👍\n\n**Generate the front end through SQLModel model configuration**\n\n\u003eZero code on the front end\n\nJust define some special fields to describe the data in your backend model, and the frontend will be automatically generated.\n\nThis method is more suitable when you have a large number of data tables to maintain and there is not much complex business logic.\n\n```python\n\nfrom typing import Optional, List\nfrom datetime import datetime\nfrom sqlmodel import SQLModel, Relationship, BIGINT\nfrom app.common.model import BaseMixin\nfrom app.common.model.field import Field\nfrom app.common.model.helper import partial_model\nfrom app.enums import IntNameEnum\nfrom app.modules.department.models import Department, DepartmentPublic\nfrom app.modules.position.models import Position, PositionPublic\nfrom .detail.models import ToyDetail, ToyDetailCreate, ToyDetailPublic\nfrom app.modules.role.models import Role, RolePublicWithoutActions\n\n\nclass ToyRoleLink(SQLModel, table=True):\n    __tablename__ = \"toy_role_link\"\n    id: int = Field(\n        sa_type=BIGINT,\n        primary_key=True,\n        index=True,\n        nullable=False,\n    )\n    toy_id: Optional[int] = Field(\n        default=None, sa_type=BIGINT, foreign_key=\"toy.id\"\n    )\n    role_id: Optional[int] = Field(\n        default=None, sa_type=BIGINT, foreign_key=\"role.id\"\n    )\n\n\nclass Select1Enum(IntNameEnum):\n    option1 = 1, \"option1\"\n    option2 = 2, \"option2\"\n    option3 = 3, \"option3\"\n\n\nclass ToyBase(SQLModel):\n    tetx1: str = Field(value_type=\"text\",\n                       title=\"text1\", description=\"description\")\n    tetx2: str = Field(default=None, value_type=\"text\", title=\"text2\")\n    textarea1: Optional[str] = Field(\n        default=None, value_type=\"textarea\", title=\"textarea1\")\n    switch1: Optional[bool] = Field(\n        default=True, value_type=\"switch\", title=\"switch1\", description=\"description\")\n    checkbox1: Optional[bool] = Field(\n        default=True, value_type=\"checkbox\", title=\"checkbox1\", description=\"description\")\n    select1: Select1Enum | None = Field(\n        enum=Select1Enum, default=Select1Enum.option1, value_type=\"select\", title=\"select1\", description=\"select1_description\")\n    department_id: Optional[int] = Field(\n        default=None,\n        title=\"department\",\n        value_type=\"referenceNode\",\n        sa_type=BIGINT,\n        reference=\"department\",\n        hide_in_list=True,\n        foreign_key=\"department.id\",\n        description=\"department_description\"\n    )\n    position_id: int = Field(\n        foreign_key=\"position.id\",\n        title=\"position\",\n        value_type=\"reference\",\n        sa_type=BIGINT,\n        reference=\"position\",\n        hide_in_list=True,\n        priority=10\n    )\n\n\nclass Toy(ToyBase, BaseMixin, table=True):\n    department: Optional[Department] = Relationship(\n        sa_relationship_kwargs={\"lazy\": \"noload\"},\n    )\n    position: Optional[Position] = Relationship(\n        sa_relationship_kwargs={\"lazy\": \"noload\"},\n    )\n    details: List[ToyDetail] = Relationship(\n        sa_relationship_kwargs={\n            \"uselist\": True,\n            \"cascade\": \"all, delete-orphan\",\n            \"lazy\": \"noload\"\n        })\n    roles: List[\"Role\"] = Relationship(\n        sa_relationship_kwargs={\"lazy\": \"noload\"},\n        link_model=ToyRoleLink\n    )\n\n\nclass ToyPublic(ToyBase):\n    id: Optional[int]\n    department: Optional[DepartmentPublic] = Field(\n        title=\"department\",\n        value_type=\"referenceNode\",\n        reference=\"department\",\n        search_key=\"department_id\"\n    )\n    position: Optional[PositionPublic] = Field(\n        title=\"position\",\n        value_type=\"reference\",\n        reference=\"position\",\n        search_key=\"position_id\",\n        priority=10\n    )\n    created_at: Optional[datetime] = None\n    details: List[ToyDetailPublic] = None\n    roles: List[RolePublicWithoutActions] = Field(\n        title=\"roles\",\n        value_type=\"referenceArray\",\n        reference=\"role\",\n        priority=9\n    )\n\n\nclass ToyCreate(ToyBase):\n    roles: Optional[List[int]] = Field(\n        default=None,\n        title=\"roles\",\n        value_type=\"referenceArray\",\n        reference=\"role\",\n        priority=9\n    )\n    details: List[ToyDetailCreate] = Field(\n        title=\"details\", value_type=\"listTable\", description=\"detail description\")\n\n\n@partial_model\nclass ToyUpdate(ToyBase):\n    roles: Optional[List[int]] = Field(\n        default=None,\n        title=\"roles\",\n        value_type=\"referenceArray\",\n        reference=\"role\",\n        priority=9\n    )\n    details: List[ToyDetailCreate] = None\n\n\n```\nThe front end automatically generates lists and forms based on the json schema returned by the back end\n\n![Toy List](resources/toy-list.png)\n![Toy Create](resources/toy-create.png)\n\n### Support for relationships\n\n#### 1. One To One\n\nCreate/Edit Mode\n\n```python\n\ndepartment_id: Optional[int] = Field(\n    default=None,\n    title=\"department\",\n    value_type=\"referenceNode\",\n    sa_type=BIGINT,\n    reference=\"department\",\n    hide_in_list=True,\n    foreign_key=\"department.id\",\n    description=\"department_description\"\n)\nposition_id: int = Field(\n    foreign_key=\"position.id\",\n    title=\"position\",\n    value_type=\"reference\",\n    sa_type=BIGINT,\n    reference=\"position\",\n    hide_in_list=True,\n    priority=10\n)\n\n```\nAdd value_type and reference attributes to the normal SQLModel foreign key configuration\n\nDifferent value_type will present different form rendering items\n\n**reference**:autocomplete.\n**referenceNode**:tree select.\n\nAlso in list mode you only need to configure\n\n```python\ndepartment: Optional[DepartmentPublic] = Field(\n    title=\"department\",\n    value_type=\"referenceNode\",\n    reference=\"department\",\n    search_key=\"department_id\"\n)\nposition: Optional[PositionPublic] = Field(\n    title=\"position\",\n    value_type=\"reference\",\n    reference=\"position\",\n    search_key=\"position_id\",\n    priority=10\n)\n```\n\n\n#### 2. One To Many\n\n```python\n\nclass ToyCreate(ToyBase):\n    details: List[ToyDetailCreate] = Field(title=\"details\", value_type=\"listTable\", description=\"detail description\")\n```\nCompared with the normal **SQLModel** relationship configuration\nYou just should to add value_type as listTable\nThe front end will automatically generate one-to-many table data maintenance\n\n![One To Many](resources/one-to-many.png)\n\n\n#### 3. Many To Many\n\n```python\nclass ToyRoleLink(SQLModel, table=True):\n    __tablename__ = \"toy_role_link\"\n    id: int = Field(\n        sa_type=BIGINT,\n        primary_key=True,\n        index=True,\n        nullable=False,\n    )\n    toy_id: Optional[int] = Field(\n        default=None, sa_type=BIGINT, foreign_key=\"toy.id\"\n    )\n    role_id: Optional[int] = Field(\n        default=None, sa_type=BIGINT, foreign_key=\"role.id\"\n    )\n\nclass Toy(ToyBase, BaseMixin, table=True):\n    roles: List[\"Role\"] = Relationship(\n        sa_relationship_kwargs={\"lazy\": \"noload\"},\n        link_model=ToyRoleLink\n    )\n\nclass ToyCreate(ToyBase):\n    roles: Optional[List[int]] = Field(\n        default=None,\n        title=\"roles\",\n        value_type=\"referenceArray\",\n        reference=\"role\",\n        priority=9\n    )\n\n```\n\nCompared with the normal **SQLModel** relationship configuration\nYou just should to add value_type as referenceArray\n\nThe front end will automatically generate a multi-select autocomplate control\n\n![Many To Many](resources/many-to-many.png)\n\n\n## How To Use It\nYou can **just fork or clone** this repository and use it as is.\n✨ It just works. ✨\n\n## Backend Development\n\nBackend docs: [backend/README.md](./backend/README.md).\n\n## Frontend Development\n\nFrontend docs: [frontend/README.md](./frontend/README.md).\n\n## Why did you use BlackPanther as the name of the project?\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"resources/Black Panther.png\" alt=\"BlackPanther is a Full stack web application scaffold,Using FastAPI,BetterCRUD,Refine and more.\" width=\"200\" height=\"auto\"\u003e\n\u003c/p\u003e\nBlack Panther is the name of a stray cat I feed. It is very cute and obedient. We have a good relationship. My daughter gave it the name, which I think is good. I hope it can live a good life.\n\n## Off Topic\nI really want to thank this project. In the loneliest moments of my life, it has always motivated me to move forward and complete these features with a high pursuit as my goal.\n\n## Author\n\n👤 **bigrivi**\n* GitHub: [bigrivi](https://github.com/bigrivi)\n\n## 🤝 Contributing\n\nContributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\nIf you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag \"enhancement\".\nDon't forget to give the project a star! Thanks again!\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## License\n\n[MIT](LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigrivi%2Fblack-panther","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigrivi%2Fblack-panther","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigrivi%2Fblack-panther/lists"}