71 lines
3 KiB
Markdown
71 lines
3 KiB
Markdown
|
|
---
|
||
|
|
kind: task
|
||
|
|
slug: pick-workspace-landing-route
|
||
|
|
title: Decide and implement the post-sign-in landing route
|
||
|
|
plan_slug: daily-driver-finish
|
||
|
|
epic_slug: shipping-the-shell
|
||
|
|
status: ready
|
||
|
|
priority: P1
|
||
|
|
tenant_id: global
|
||
|
|
owner: unassigned
|
||
|
|
cursor_todo_id: null
|
||
|
|
updated_at: "2026-06-01"
|
||
|
|
---
|
||
|
|
|
||
|
|
# Task summary
|
||
|
|
|
||
|
|
After sign-in, where should a user land? Today they land on `[workspaceSlug]/page.tsx`, which is a mostly-decorative dashboard. Make a deliberate decision and implement it.
|
||
|
|
|
||
|
|
## Description
|
||
|
|
|
||
|
|
### The decision
|
||
|
|
|
||
|
|
Three reasonable defaults:
|
||
|
|
|
||
|
|
1. **Workspace home** (current) — only good once `Task-wire-workspace-home-dashboard` lands. Until then, it's a mockup.
|
||
|
|
2. **Planner** — `[workspaceSlug]/planner`, the most "active" view. Lots of tenants will prefer this.
|
||
|
|
3. **Last visited surface** — store `last_visited_path` on the user (or in `localStorage`) and redirect there. Best UX but requires a column and a tiny middleware.
|
||
|
|
|
||
|
|
Recommendation: **(1) workspace home, but only after** `Task-wire-workspace-home-dashboard` has landed. If that task isn't done yet, ship a redirect to `(2) /planner` as the interim default and remove the redirect once the home page is real.
|
||
|
|
|
||
|
|
### Implementation
|
||
|
|
|
||
|
|
1. The redirect target for an authenticated user with no specific URL is decided in `apps/web/middleware.ts` (if it exists) or via the NextAuth `pages.signIn` and the post-sign-in `callbackUrl`.
|
||
|
|
2. Verify `signIn(provider, { callbackUrl: "/" })` lands somewhere sensible. The current top-level page should redirect to the user's first workspace's slug. Check `apps/web/app/page.tsx` (the unauth root) and `apps/web/app/(app)/page.tsx` (the auth root).
|
||
|
|
3. The redirect must use `workspace_members` to find a workspace the user belongs to. Don't trust the slug from a query param without verifying membership.
|
||
|
|
|
||
|
|
### Anti-goals
|
||
|
|
|
||
|
|
- Don't introduce a "switcher" workflow as part of this task. If users have multiple workspaces today, just pick the first one (oldest membership) and land them there.
|
||
|
|
- Don't add new DB columns for `last_visited_path` unless you're committing to do the full implementation. The simple redirect is fine for now.
|
||
|
|
|
||
|
|
## Subtasks
|
||
|
|
|
||
|
|
- [ ] Read `apps/web/middleware.ts` and `apps/web/app/(app)/layout.tsx` to find the existing landing logic.
|
||
|
|
- [ ] Decide: workspace home or planner. Document the choice in this task before implementing.
|
||
|
|
- [ ] Implement the redirect, scoped through `workspace_members`.
|
||
|
|
- [ ] Verify with a fresh OAuth sign-in that the user lands somewhere useful.
|
||
|
|
|
||
|
|
## Owner or assignee
|
||
|
|
|
||
|
|
Unassigned
|
||
|
|
|
||
|
|
## Status
|
||
|
|
|
||
|
|
ready
|
||
|
|
|
||
|
|
## Estimation
|
||
|
|
|
||
|
|
S
|
||
|
|
|
||
|
|
## Acceptance criteria
|
||
|
|
|
||
|
|
- [ ] A fresh sign-in lands on a page that shows real state, not a mockup.
|
||
|
|
- [ ] Landing logic resolves workspace via `workspace_members` (no URL-trust).
|
||
|
|
- [ ] Users with zero workspaces don't 404 — they hit an onboarding flow or the workspace-creation dialog. (If neither exists, file a follow-up task and gate this acceptance criterion on it.)
|
||
|
|
|
||
|
|
## Links to related Epic / Plan
|
||
|
|
|
||
|
|
- Epic: `./Epic-shipping-the-shell.md`
|
||
|
|
- Plan: `../Plan-daily-driver-finish.md`
|