This example demonstrates a full-featured Trusted plugin. It goes beyond simple handlers to show how to structure SQLAlchemy Models, Pydantic Schemas, and Automated Tasks (Scheduler) within a single isolated module.
By using UserCreate in the FastAPI route, Xcore (via FastAPI) automatically performs request validation. If the email is invalid, a 422 Unprocessable Entity is returned before the plugin code even runs.
The @self.scheduler.interval decorator in on_start ensures that every tenant running this plugin has its own daily report job. Because Xcore multi-tenancy is active, the self.db call inside the job is automatically scoped to the correct tenant.
This plugin is loaded in Wave 1 if it requires db and cache (which are initialized in Wave 0). This ensures all services are READY before the scheduler tries to start the maintenance job.
@pytest.mark.asyncioasyncdeftest_complete_flow(xcore_app):client=AsyncClient(app=xcore_app,base_url="http://test")# 1. Test Validationbad_res=awaitclient.post("/plugin/user_manager/v2/register",json={"email":"not-an-email"})assertbad_res.status_code==422# 2. Test Successres=awaitclient.post("/plugin/user_manager/v2/register",json={"username":"alice","email":"alice@xcore.dev"},headers={"X-Tenant-ID":"test_tenant"})assertres.status_code==201# 3. Test Scheduler Presencejobs=xcore_app.services.get("scheduler").jobs()assertany("daily_user_report"inj["id"]forjinjobs)