Orgs: let any user create an organization and become its admin
Organization writes were superadmin-only, so standing up a tenant needed an out-of-band superadmin. Creating one is now self-service, and an admin manages the org they belong to. - POST /api/orgs is open to any authenticated user. A creator who isn't a superadmin must have no organization yet (a single-valued membership relation means a second one would abandon the first), and is promoted to the new org's admin and first member in the same request. If that promotion fails the org is rolled back, so it is never left stranded with nobody able to administer it. Superadmins still create tenants without joining them. - PATCH/DELETE are manager-gated and scope an admin to their own org. An admin deletes theirs only as its sole member: they are detached and demoted to a plain user before the record goes, so the org is empty when it is removed. Other members still block deletion with a 409. - /api/me now carries organization + organizationName, which the clients need to tell "no org yet" from "org you administer". The panel, Web App (new OrgManager.vue in Settings) and Phone App (new _OrganizationSection) all mirror the server's gates rather than re-deciding them. The Phone App cached its role at login and gates the Users tab on it, so AuthService.adoptRole refreshes that from the profile instead of making a freshly promoted admin sign in again. Covered by orgs_test.go, which drives the real handler + middleware chain against a stand-in PocketBase: promotion, the already-a-member refusal, superadmin staying unattached, the rollback, own-org scoping, the detach-and-demote, and the blocking-member 409. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
358ee68f94
commit
cd16d4383f
30 files changed
+1193
-63
No files matched your search
@@ -108,7 +108,7 @@
|
||||
"title": "Brugere",
|
||||
"subtitleAll": "Konti på tværs af alle organisationer.",
|
||||
"subtitleOrg": "Konti i din organisation.",
|
||||
"subtitleOrgsNote": "Organisationer tildeles i API-panelet.",
|
||||
"subtitleOrgsNote": "Organisationer administreres under Indstillinger.",
|
||||
"addUser": "Tilføj bruger",
|
||||
"colEmail": "E-mail",
|
||||
"colName": "Navn",
|
||||
@@ -199,6 +199,23 @@
|
||||
"saveBio": "Gem beskrivelse"
|
||||
},
|
||||
|
||||
"org": {
|
||||
"title": "Organisation",
|
||||
"titleAll": "Organisationer",
|
||||
"subtitleOwn": "Den organisation du administrerer",
|
||||
"subtitleNone": "Opret en for at administrere dit eget team",
|
||||
"subtitleAll": "Enheder, som brugere tilhører",
|
||||
"nameLabel": "Organisationsnavn",
|
||||
"namePlaceholder": "Acme Fleet",
|
||||
"newOrg": "Ny organisation",
|
||||
"create": "Opret organisation",
|
||||
"createHint": "Du bliver dens administrator og kan derefter tilføje og administrere brugere.",
|
||||
"rename": "Omdøb",
|
||||
"empty": "Ingen organisationer endnu.",
|
||||
"confirmDelete": "Slet organisationen „{name}“? Dette kan ikke fortrydes.",
|
||||
"confirmDeleteOwn": "Slet din organisation „{name}“? Du fjernes fra den og bliver en almindelig bruger. Dette kan ikke fortrydes."
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"title": "Privatliv og sikkerhed",
|
||||
"signOut": "Log ud",
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
"title": "Users",
|
||||
"subtitleAll": "Accounts across every organization.",
|
||||
"subtitleOrg": "Accounts in your organization.",
|
||||
"subtitleOrgsNote": "Organizations are assigned in the API panel.",
|
||||
"subtitleOrgsNote": "Organizations are managed in Settings.",
|
||||
"addUser": "Add user",
|
||||
"colEmail": "Email",
|
||||
"colName": "Name",
|
||||
@@ -274,6 +274,23 @@
|
||||
"controlDisconnected": "Not connected"
|
||||
},
|
||||
|
||||
"org": {
|
||||
"title": "Organization",
|
||||
"titleAll": "Organizations",
|
||||
"subtitleOwn": "The organization you administer",
|
||||
"subtitleNone": "Create one to manage your own team",
|
||||
"subtitleAll": "Tenants users belong to",
|
||||
"nameLabel": "Organization name",
|
||||
"namePlaceholder": "Acme Fleet",
|
||||
"newOrg": "New organization",
|
||||
"create": "Create organization",
|
||||
"createHint": "You'll become its admin and can then add and manage users.",
|
||||
"rename": "Rename",
|
||||
"empty": "No organizations yet.",
|
||||
"confirmDelete": "Delete the organization “{name}”? This cannot be undone.",
|
||||
"confirmDeleteOwn": "Delete your organization “{name}”? You'll be removed from it and become a regular user. This cannot be undone."
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"title": "Privacy & security",
|
||||
"signOut": "Sign out",
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
"title": "Użytkownicy",
|
||||
"subtitleAll": "Konta ze wszystkich organizacji.",
|
||||
"subtitleOrg": "Konta w Twojej organizacji.",
|
||||
"subtitleOrgsNote": "Organizacje przypisuje się w panelu API.",
|
||||
"subtitleOrgsNote": "Organizacjami zarządza się w Ustawieniach.",
|
||||
"addUser": "Dodaj użytkownika",
|
||||
"colEmail": "E-mail",
|
||||
"colName": "Imię i nazwisko",
|
||||
@@ -203,6 +203,23 @@
|
||||
"saveBio": "Zapisz opis"
|
||||
},
|
||||
|
||||
"org": {
|
||||
"title": "Organizacja",
|
||||
"titleAll": "Organizacje",
|
||||
"subtitleOwn": "Organizacja, którą administrujesz",
|
||||
"subtitleNone": "Utwórz ją, aby zarządzać własnym zespołem",
|
||||
"subtitleAll": "Podmioty, do których należą użytkownicy",
|
||||
"nameLabel": "Nazwa organizacji",
|
||||
"namePlaceholder": "Acme Fleet",
|
||||
"newOrg": "Nowa organizacja",
|
||||
"create": "Utwórz organizację",
|
||||
"createHint": "Zostaniesz jej administratorem i będziesz móc dodawać użytkowników oraz nimi zarządzać.",
|
||||
"rename": "Zmień nazwę",
|
||||
"empty": "Brak organizacji.",
|
||||
"confirmDelete": "Usunąć organizację „{name}”? Tego nie można cofnąć.",
|
||||
"confirmDeleteOwn": "Usunąć Twoją organizację „{name}”? Zostaniesz z niej usunięty i staniesz się zwykłym użytkownikiem. Tego nie można cofnąć."
|
||||
},
|
||||
|
||||
"privacy": {
|
||||
"title": "Prywatność i bezpieczeństwo",
|
||||
"signOut": "Wyloguj się",
|
||||
|
||||
Reference in new issue
Block a user