mattstanbrell sluck .cursorrules file for TypeScript

# Slack Clone - Basic MVP Requirements

## 1. Workspaces
- Create and join workspaces
- Workspace name and optional description
- Member roles (owner, admin, member)
- Workspace switching
- Basic workspace settings

## 2. Authentication
- Google sign-in only
- Protected routes
- Basic user profile (name, email, avatar)

## 3. Channels
- Create and join public channels within a workspace
- Channel name and optional description
- List of channel members
- Basic channel navigation

## 4. Direct Messaging
- One-on-one messaging within a workspace
- Conversation list in sidebar
- Basic online/offline status

## 5. Real-time Messaging
- Send and receive messages instantly
- Basic text messages
- Message history
- Edit and delete own messages

## 6. Channel/DM Organization
- Simple sidebar navigation
- List of channels
- List of direct messages
- Basic unread indicators

## 7. File Sharing
- Upload and share images
- Basic image preview
- Simple file list per channel

## 8. User Presence & Status
- Online/offline status
- Custom status message
- Last seen timestamp

## 9. Thread Support
- Create threads on messages
- View threaded conversations
- Thread notification badges

## 10. Emoji Reactions
- Add/remove reactions to messages
- Basic emoji picker
- Reaction counts


# Database Schema

## Workspaces table
```sql
create table workspaces (
  id uuid primary key default uuid_generate_v4(),
  name text not null,
  slug text unique not null,
  description text,
  created_by uuid references users(id) on delete set null,
  created_at timestamptz default now(),
  updated_at timestamptz default now(),
  invite_code text unique,
  invite_expires_at timestamptz,
  invite_is_revoked boolean default false
);

create index workspaces_invite_code_idx on workspaces(invite_code);
```

## Workspace members table
```sql
create table workspace_members (
  workspace_id uuid references workspaces(id) on delete cascade,
  user_id uuid references users(id) on delete cascade,
  role text not null check (role in ('owner', 'admin', 'member')) default 'member',
  joined_at timestamptz default now(),
  primary key (workspace_id, user_id)
);
```

## Users table
```sql
create table users (
  id uuid primary key default uuid_generate_v4(),
  created_at timestamptz default now(),
  email text unique not null,
  name text not null,
  avatar_url text,
  status text,
  last_seen timestamptz
);
```

## Channels table
```sql
create table channels (
  id uuid primary key default uuid_generate_v4(),
  workspace_id uuid references workspaces(id) on delete cascade not null,
  name text not null,
  description text,
  created_by uuid references users(id) on delete set null,
  created_at timestamptz default now(),
  updated_at timestamptz default now(),
);
```

## Channel members table
```sql
create table channel_members (
  channel_id uuid references channels(id) on delete cascade,
  user_id uuid references users(id) on delete cascade,
  role text not null check (role in ('admin', 'member')) default 'member',
  joined_at timestamptz default now(),
  primary key (channel_id, user_id)
);
```

## Conversations table
```sql
create table conversations (
  id uuid primary key default uuid_generate_v4(),
  workspace_id uuid references workspaces(id) on delete cascade not null,
  created_at timestamptz default now(),
  updated_at timestamptz default now(),
  last_message_at timestamptz,
  type text not null check (type in ('direct', 'group')) default 'direct'
);
```

## Conversation participants table
```sql
create table conversation_participants (
  conversation_id uuid references conversations(id) on delete cascade,
  user_id uuid references users(id) on delete cascade,
  joined_at timestamptz default now(),
  last_read_at timestamptz,
  primary key (conversation_id, user_id)
);
```

## Messages table
```sql
create table messages (
  id uuid primary key default uuid_generate_v4(),
  conversation_id uuid references conversations(id) on delete cascade,
  channel_id uuid references channels(id) on delete cascade,
  user_id uuid references users(id) on delete cascade,
  recipient_id uuid references users(id) on delete cascade,
  parent_id uuid references messages(id) on delete cascade,
  thread_participant boolean default false,
  content text not null,
  created_at timestamptz default now(),
  updated_at timestamptz default now(),
  -- messages must belong to either a conversation or channel
  constraint message_container_check check (
    (conversation_id is null and channel_id is not null) or
    (conversation_id is not null and channel_id is null)
  )
);

create index messages_user_id_idx on messages(user_id);
create index messages_recipient_id_idx on messages(recipient_id);
create index messages_parent_id_idx on messages(parent_id);
```

## Enable Row Level Security
```sql
alter table workspaces enable row level security;
alter table workspace_members enable row level security;
alter table channels enable row level security;
alter table messages enable row level security;
alter table channel_members enable row level security;
alter table channel_invites enable row level security;
alter table conversations enable row level security;
alter table conversation_participants enable row level security;
```

## Enable Realtime
```sql
alter publication supabase_realtime add table workspaces;
alter publication supabase_realtime add table workspace_members;
alter publication supabase_realtime add table channels;
alter publication supabase_realtime add table messages;
alter publication supabase_realtime add table channel_invites;
alter publication supabase_realtime add table conversations;
alter publication supabase_realtime add table conversation_participants;
```


# Tech Stack

## Core Framework
- **Next.js 14+** (App Router)
- **React 19**
- **TypeScript**

## Authentication & Database
- **NextAuth.js** (v5 beta) - Google authentication
- **Supabase** - PostgreSQL database with realtime capabilities
  - Database
  - Row Level Security
  - Realtime subscriptions
  - Storage (for file uploads)

## UI Components & Styling
- **Tailwind CSS**
- **shadcn/ui**


# Notes

In Next.js 15+, dynamic route parameters (like `params` and `searchParams`) are asynchronous.
You must await the entire `params` object before accessing its properties.

Use `npx shadcn@latest` not `npx shadcn-ui@latest`.
auth.js
css
golang
javascript
next.js
nextauth
postgresql
react
+5 more

First Time Repository

TypeScript

Languages:

CSS: 3.8KB
JavaScript: 0.1KB
TypeScript: 104.8KB
Created: 1/7/2025
Updated: 1/9/2025

All Repositories (1)