diff --git a/apps/api/src/db/organization_config.py b/apps/api/src/db/organization_config.py index a54e537e..5812179e 100644 --- a/apps/api/src/db/organization_config.py +++ b/apps/api/src/db/organization_config.py @@ -82,6 +82,7 @@ class OrgGeneralConfig(BaseModel): color: str = "normal" watermark: bool = True + # Cloud class OrgCloudConfig(BaseModel): plan: Literal["free", "standard", "pro"] = "free" @@ -90,10 +91,11 @@ class OrgCloudConfig(BaseModel): # Main Config class OrganizationConfigBase(BaseModel): - config_version: str = "1.2" + config_version: str = "1.3" general: OrgGeneralConfig features: OrgFeatureConfig cloud: OrgCloudConfig + landing: dict = {} class OrganizationConfig(SQLModel, table=True): diff --git a/apps/api/src/routers/orgs.py b/apps/api/src/routers/orgs.py index e6025829..e3cdc735 100644 --- a/apps/api/src/routers/orgs.py +++ b/apps/api/src/routers/orgs.py @@ -40,6 +40,7 @@ from src.services.orgs.orgs import ( update_org_preview, update_org_signup_mechanism, update_org_thumbnail, + update_org_landing, ) @@ -413,3 +414,17 @@ async def api_delete_org( """ return await delete_org(request, org_id, current_user, db_session) + + +@router.put("/{org_id}/landing") +async def api_update_org_landing( + request: Request, + org_id: int, + landing_object: dict, + current_user: PublicUser = Depends(get_current_user), + db_session: Session = Depends(get_db_session), +): + """ + Update organization landing object + """ + return await update_org_landing(request, landing_object, org_id, current_user, db_session) diff --git a/apps/api/src/services/install/install.py b/apps/api/src/services/install/install.py index 84841fb4..aea4551e 100644 --- a/apps/api/src/services/install/install.py +++ b/apps/api/src/services/install/install.py @@ -330,7 +330,7 @@ def install_create_organization(org_object: OrganizationCreate, db_session: Sess # Org Config org_config = OrganizationConfigBase( - config_version="1.2", + config_version="1.3", general=OrgGeneralConfig( enabled=True, color="normal", @@ -354,7 +354,8 @@ def install_create_organization(org_object: OrganizationCreate, db_session: Sess cloud=OrgCloudConfig( plan='free', custom_domain=False - ) + ), + landing={} ) org_config = json.loads(org_config.json()) diff --git a/apps/api/src/services/orgs/orgs.py b/apps/api/src/services/orgs/orgs.py index 447e26b1..c66e80b3 100644 --- a/apps/api/src/services/orgs/orgs.py +++ b/apps/api/src/services/orgs/orgs.py @@ -714,6 +714,57 @@ async def upload_org_preview_service( "filename": name_in_disk } +async def update_org_landing( + request: Request, + landing_object: dict, + org_id: int, + current_user: PublicUser | AnonymousUser, + db_session: Session, +): + statement = select(Organization).where(Organization.id == org_id) + result = db_session.exec(statement) + + org = result.first() + + if not org: + raise HTTPException( + status_code=404, + detail="Organization not found", + ) + + # RBAC check + await rbac_check(request, org.org_uuid, current_user, "update", db_session) + + # Get org config + statement = select(OrganizationConfig).where(OrganizationConfig.org_id == org.id) + result = db_session.exec(statement) + + org_config = result.first() + + if org_config is None: + logging.error(f"Organization {org_id} has no config") + raise HTTPException( + status_code=404, + detail="Organization config not found", + ) + + # Convert to OrganizationConfigBase model and back to ensure all fields exist + config_model = OrganizationConfigBase(**org_config.config) + + # Update the landing object + config_model.landing = landing_object + + # Convert back to dict and update + updated_config = json.loads(config_model.json()) + org_config.config = updated_config + org_config.update_date = str(datetime.now()) + + db_session.add(org_config) + db_session.commit() + db_session.refresh(org_config) + + return {"detail": "Landing object updated"} + ## 🔒 RBAC Utils ##