mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-20 03:01:26 +02:00
feat(spaces): auto-create personal space on signup via Better Auth hook
Wires databaseHooks.user.create.after to call createPersonalSpaceFor, which provisions a Better Auth organization of type='personal' with the user as owner. Every signup now produces a usable default space — no UI code needed to bootstrap it. Details: - Slug derived from email local-part, lowercase, alphanumerics + hyphens, max 30 chars, random fallback if nothing usable remains. - Reserved-slug list (me/admin/api/auth/…) blocks system-route clashes. - Collision resolver appends -2, -3, … up to 999 before falling back to a random suffix. Tests cover both the DB-taken and reserved-slug cases via an injectable SlugTakenLookup (no DB needed for unit tests). - Idempotent: if a personal space already exists for the user, returns it instead of creating a duplicate. Guards against retry double-signup. - Failure propagates — an orphan user without a personal space is worse than a retry-able signup error. Existing dev users will need a backfill or a re-provisioning of the dev DB — new users are unaffected. 12 tests pass (23 total across the spaces module). Plan: docs/plans/spaces-foundation.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5af96bfeff
commit
da1bb2d6e9
4 changed files with 266 additions and 1 deletions
|
|
@ -38,7 +38,11 @@ import {
|
|||
} from '../email/send';
|
||||
import { sourceAppStore, passwordResetRedirectStore } from './stores';
|
||||
import { TRUSTED_ORIGINS } from './sso-origins';
|
||||
import { assertValidSpaceMetadataForCreate, assertSpaceIsDeletable } from '../spaces';
|
||||
import {
|
||||
assertValidSpaceMetadataForCreate,
|
||||
assertSpaceIsDeletable,
|
||||
createPersonalSpaceFor,
|
||||
} from '../spaces';
|
||||
|
||||
// Re-export so existing imports (`import { TRUSTED_ORIGINS } from './better-auth.config'`)
|
||||
// keep working. New code should import from './sso-origins' directly.
|
||||
|
|
@ -202,6 +206,32 @@ export function createBetterAuth(databaseUrl: string) {
|
|||
updateAge: 60 * 60 * 24, // Update session once per day
|
||||
},
|
||||
|
||||
/**
|
||||
* Database hooks — lifecycle callbacks for core tables.
|
||||
*
|
||||
* `user.create.after` runs after a successful signup and provisions
|
||||
* the user's personal Space (a Better Auth organization of type
|
||||
* `personal`). Every user needs one because modules store private
|
||||
* data like mood, dreams, sleep there. Failure propagates: an
|
||||
* orphan user without a personal space is a worse state than a
|
||||
* retry-able signup error.
|
||||
*
|
||||
* See docs/plans/spaces-foundation.md and ../spaces/personal-space.ts.
|
||||
*/
|
||||
databaseHooks: {
|
||||
user: {
|
||||
create: {
|
||||
after: async (user) => {
|
||||
await createPersonalSpaceFor(db, {
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Base URL for callbacks and redirects
|
||||
baseURL: process.env.BASE_URL || 'http://localhost:3001',
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue