Commit graph

3 commits

Author SHA1 Message Date
Paulo Castellano
3e15144399 chore: remove unused Pennant package and dead user-timezone handling
Pennant: all feature flags were replaced by BillingCycle, so remove the package
(composer), the now-empty app/Features discovery, the pennant-development skill,
and replace the create_features_table migration with a drop_features_table.

Timezone: the registration flow collected a user timezone (seeder, request
validation, hidden field) but no timezone column ever existed and CreateUser
discarded it. Remove the dead handling, the orphaned Timezone rule, and the
tests that covered the now-removed validation.
2026-06-22 13:37:38 -03:00
Paulo Castellano
b7374c1adb feat(onboarding): auto-create a default workspace at signup
- CreateUser now provisions a default "{name}'s Workspace" for non-invite
  signups (email, Google, GitHub, seeder), with the owner as Admin and
  current_workspace_id set. Invite signups still skip it (they join the
  inviter's workspace on acceptance).
- UserSeeder drops its now-redundant explicit CreateWorkspace call.
- After Stripe checkout, billing/processing lands the user on the social
  accounts screen with the connect dialog open (was: calendar), so onboarding
  flows straight into connecting an account.

Quantity stays correct (1 workspace → checkout quantity 1). The first workspace
is created without brand details; brand setup remains available in Settings and
on the create-workspace screen for additional workspaces.
2026-06-22 08:18:19 -03:00
Paulo Castellano
74bd88d3d6 feat(auth): self-hosted registration gate + admin seeder (closes #46)
Self-hosted installs (SELF_HOSTED=true, the default) now close /register
to the public. Workspace invites still work — the AcceptInvite page
links into /register with ?invite={id}, the middleware persists that
into the session, and POST /register passes through.

- EnsureRegistrationEnabled middleware gates GET/POST /register.
  Accepts ?invite=… (URL) or pending_invite_id (session) as the pass.
- RegisteredUserController::store clears the marker after signup.
- AcceptInvite.vue passes invite.id in the register link's query string.
- Login.vue hides the "Sign up" link when self_hosted.
- UserSeeder bootstraps a single admin (admin@trypost.it / password).
  Idempotent; not wired into DatabaseSeeder — operator runs
  `php artisan db:seed --class=UserSeeder` per the install docs.
- Tests cover both flag values for every changed surface.

Docs PR: see trypost-docs self-hosting/installation.mdx step 3.
2026-05-19 11:45:16 -03:00