Skip to content

Epic: Teams + Membership + Invite Tokens (Secure Team Access) #27

Description

@kendymann

Description

Today, the app scopes data by a shared teamKey string (stored on users and ETL tables). This makes “team code” function like a shared secret: anyone who learns/guesses it can join that workspace.

This epic upgrades the system to a proper model where:

  • Teams are first-class records
  • Users gain access only through explicit membership
  • Joining a team happens via secure invite tokens (not guessable codes)
  • Admins can manage members/invites (revoke access without rotating a shared code)

Goals

  • Eliminate “guess team code → join workspace” risk
  • Support revocation (remove a member without affecting everyone)
  • Provide auditability (who invited whom, when used)
  • Lay groundwork for roles (ADMIN vs MEMBER)

TODOs

  • Data model (DB + JPA entities)
    • Create teams table/entity
    • Create team_memberships table/entity (user ↔ team, role)
    • Create team_invites table/entity (token, expiry, used state)
  • Migration plan
    • Decide migration tool (Flyway/Liquibase recommended) or scripted SQL
    • Backfill:
      • Create teams for existing teamKey values
      • Create memberships for existing users based on teamKey
      • Migrate ETL tables from team_keyteam_id (or bridge both temporarily)
  • Auth/team context
    • Implement “active team” resolution for a logged-in user
      • If no memberships → redirect to create team
      • If 1 membership → auto-select
      • If multiple → add team picker (or store in session)
  • Invite workflow (secure join)
    • Admin-only: generate invite token (expiry + revocable)
    • Public: GET /join?token=... to redeem invite
    • Create membership on successful redemption
    • Mark invite as used (single-use) or allow multi-use (decide)
  • Admin workflow
    • View members list
    • Remove member (revokes access)
    • View/revoke invites
  • Refactor application logic to use membership/teamId scoping
    • Update controllers/services/repositories that currently take teamKey
    • Replace ...ByTeamKey... queries with ...ByTeamId...
  • Tests
    • Team creation creates ADMIN membership
    • Invite redemption creates MEMBER membership
    • Removed members cannot access team-scoped endpoints
    • Data is correctly isolated by teamId

Blockers / Decisions

  • Single-team-per-user only, or multi-team with switching?
  • Invite tokens: single-use or reusable link?
  • Team roles needed now (ADMIN/MEMBER) or later?

Notes

This epic can be implemented incrementally:

  1. Add Teams/Memberships/Invites alongside current teamKey scoping (bridge phase)
  2. Migrate ETL partitioning from teamKey columns to teamId columns (refactor phase)
  3. Remove legacy teamKey usage once migration is complete

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions