# Project export: Hive

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 12.0
- Tagline: A Chatbot for Buzzing Collaboration
- Devpost: https://devpost.com/software/hive-fgq7d1
- GitHub: https://github.com/tupdaily/hive
- Video: https://www.youtube.com/embed/xUWXO45aCJM?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 2 GitHub contributor(s) — Peter Choi (25 commits), Daniel Martin (4 commits)

## Devpost submission (written by the team)

### Inspiration

During our internships this past summer, we both noticed that project scheduling systems are typically very slow, out of date, and hard to use. We wanted to change that, so we made Hive, a fully automated agent-powered workflow system that allows for efficient communication of project statuses via Letta agents.

### What it does

In this system, every employee is represented by a Letta agent. Projects are represented as a shared memory block, or shared context between relevant agents. Business owners can assign employees to projects, and those employee's agents will be able to read, modify, and interpret those shared memory blocks. This is much cleaner and easier to use than previous project management systems because rather than combing through massive excel files or unorganized notions, employees and admins can simply ask an agent about the status of the project, or tell it what work they've done for the project and the agent will take care of all of the organization automatically. This leads to a much more streamlined workflow, and an overall more productive system.

### How we built it

First we had to get the agent generation system working. This would trigger whenever a new employee signs up because every employee needs their own agent. After this, we implemented the shared memory block flow where admins could initialize new projects and assign employees to them. Lastly, we worked on a basic frontend that is familiar and easy to use.

### Challenges we ran into

The internet connection was singlehandedly the biggest limiting factor in our process. For multiple hours, we couldn't use github due to a bad connection, and even when it was working general research and progress was greatly slowed. In the beginning, we also struggled to come up with an idea, and ultimately didn't start coding until quite a few hours into the challenge.

### Accomplishments we're proud of

We are proud of delivering on our agreed upon MVP throughout the internet struggles. We also spent a lot of time learning the details of agents and the Letta flow, which resulted in a much deeper understanding than we had before.

### What we learned

We learned that in the future, designing a project and setting clear roles for participants is very important. If we had prepared a little more beforehand, we would have had a lot more time, and could have gotten some more of our reach goals for this project.

### What's next

We really wanted to implement MCP Server stuff into the agents, but we were ultimately unable to fully implement this due to the internet problems. In the future we hope to expand on this idea and fully implement it because it would make a huge difference in productivity overall.

## README (from the GitHub repository)

# Hive AI Team

A collaborative AI application where teams can have individual AI agents with shared and personal memory blocks, built with Letta and TypeScript.

## Features

### 🤖 AI Agent System
- **Individual Agents**: Each team member gets their own AI agent with unique personality and work preferences
- **Shared Memory**: Company-wide knowledge base accessible to all agents
- **Personal Memory**: Individual memory blocks storing agent-specific knowledge and interactions
- **Smart Queries**: Agents can answer questions about projects, team members, and company information

### 👥 Team Management
- **User Authentication**: Secure login/registration system with JWT tokens
- **Role-Based Access**: Admin and employee roles with different permissions
- **Agent Creation**: Users can create and customize their AI agents
- **Project Management**: Admins can create projects and assign agents to them

### 🎛️ Admin Console
- **Dashboard**: Overview of users, agents, projects, and memory blocks
- **User Management**: View and manage all team members
- **Agent Management**: Monitor and manage all AI agents
- **Memory Management**: Add and manage shared knowledge blocks
- **Project Management**: Create projects and assign team members

### 🌐 Web Interface
- **Modern UI**: Clean, responsive interface built with Tailwind CSS
- **Real-time Queries**: Interactive chat interface with AI agents
- **Agent Management**: Easy creation and management of personal agents
- **Admin Panel**: Comprehensive admin interface for team management

## Technology Stack

- **Backend**: Node.js, Express.js, TypeScript
- **AI Integration**: Claude AI (Anthropic)
- **Database**: SQLite with custom ORM
- **Authentication**: JWT with bcrypt password hashing
- **Frontend**: Vanilla JavaScript with Tailwind CSS
- **Validation**: Zod for request validation

## Quick Start

### Prerequisites
- Node.js (v16 or higher)
- npm or yarn

### Installation

1. **Clone the repository**
   ```bash
   git clone <repository-url>
   cd hive
   ```

2. **Install dependencies**
   ```bash
   npm install
   ```

3. **Set up environment variables**
   ```bash
   cp env.example .env
   ```
   
   Edit `.env` file with your configuration:
   ```env
   DATABASE_URL=./data/hive.db
   JWT_SECRET=your-super-secret-jwt-key-here
   PORT=3001
   NODE_ENV=development
   ANTHROPIC_API_KEY=your-anthropic-api-key-here
   ```

4. **Start the development server**
   ```bash
   npm run dev
   ```

5. **Open your browser**
   Navigate to `http://localhost:3001`

### First Time Setup

1. **Register an admin account**
   - Go to the registration form
   - Select "Admin" role
   - Create your account

2. **Create your first agent**
   - Login with your admin account
   - Click "Create Agent"
   - Define the agent's personality and work preferences

3. **Add shared knowledge**
   - Use the admin panel to add company-wide information
   - This knowledge will be available to all agents

## API Endpoints

### Authentication
- `POST /api/auth/register` - Register new user
- `POST /api/auth/login` - Login user

### Agents
- `GET /api/agents/my-agents` - Get user's agents
- `POST /api/agents` - Create new agent
- `GET /api/agents/:id` - Get specific agent
- `PUT /api/agents/:id` - Update agent
- `DELETE /api/agents/:id` - Delete agent
- `POST /api/agents/:id/query` - Query agent

### Admin
- `GET /api/admin/stats` - Get dashboard statistics
- `GET /api/admin/users` - Get all users
- `GET /api/admin/agents` - Get all agents
- `GET /api/admin/projects` - Get all projects
- `POST /api/admin/projects` - Create project
- `POST /api/admin/memory-blocks` - Create memory block

## Database Schema

### Users
- `id` - Unique identifier
- `email` - User email (unique)
- `name` - User display name
- `password_hash` - Hashed password
- `role` - 'admin' or 'employee'

### Agents
- `id` - Unique identifier
- `user_id` - Owner user ID
- `name` - Agent name
- `personality` - Agent personality description
- `work_preferences` - JSON array of work preferences
- `is_active` - Boolean active status

### Projects
- `id` - Unique identifier
- `name` - Project name
- `description` - Project description
- `status` - 'active', 'completed', or 'paused'

### Memory Blocks
- `id` - Unique identifier
- `type` - 'shared' or 'individual'
- `agent_id` - Agent ID (for individual blocks)
- `content` - Memory content
- `metadata` - JSON metadata

## Development

### Project Structure
```
src/
├── ai/                 # AI agent system
│   ├── agent.ts       # Individual AI agent
│   └── agentManager.ts # Agent management
├── auth/              # Authentication system
│   └── auth.ts        # Auth service
├── database/          # Database layer
│   ├── connection.ts  # Database connection
│   └── schema.sql     # Database schema
├── middleware/        # Express middleware
│   └── auth.ts        # Auth middleware
├── routes/            # API routes
│   ├── auth.ts        # Auth routes
│   ├── agents.ts      # Agent routes
│   └── admin.ts       # Admin routes
├── types/             # TypeScript types
│   └── index.ts       # Type definitions
├── public/            # Frontend files
│   ├── index.html     # Main HTML
│   └── app.js         # Frontend JavaScript
├── app.ts             # Express app setup
└── index.ts           # Application entry point
```

### Available Scripts
- `npm run dev` - Start development server with hot reload
- `npm run build` - Build TypeScript to JavaScript
- `npm start` - Start production server
- `npm run lint` - Run ESLint
- `npm run type-check` - Run TypeScript type checking

### Adding New Features

1. **New API Endpoints**
   - Add routes in `src/routes/`
   - Update types in `src/types/index.ts`
   - Add database methods in `src/database/connection.ts`

2. **New AI Features**
   - Extend `src/ai/agent.ts` for new agent capabilities
   - Update `src/ai/agentManager.ts` for management features

3. **Frontend Updates**
   - Modify `src/public/index.html` for UI changes
   - Update `src/public/app.js` for functionality

## Configuration

### Environment Variables
- `DATABASE_URL` - SQLite database file path
- `JWT_SECRET` - Secret key for JWT tokens
- `PORT` - Server port (default: 3000)
- `NODE_ENV` - Environment (development/production)
- `ANTHROPIC_API_KEY` - Anthropic Claude API key

### Database
The application uses SQLite for simplicity. For production, consider migrating to PostgreSQL or MySQL by updating the database connection in `src/database/connection.ts`.

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## License

MIT License - see LICENSE file for details

## Support

For questions or issues, please open an issue on GitHub or contact the development team.

## Detected evidence (automated analysis)

Indexed codebase: 26 recognized source files, 139 KB.
- Anthropic (technology) — detected in the code
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- HTML (language) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- Supabase (technology) — detected in the code
- TypeScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (33 of 33)

```
.gitignore
data/hive.db
env.example
package.json
README.md
src/ai/agent.ts
src/ai/agentManager.ts
src/app.ts
src/auth/auth.ts
src/database/connection.ts
src/database/supabase-schema.sql
src/index.ts
src/middleware/auth.ts
src/public/App.tsx
src/public/components/AdminConsole.tsx
src/public/components/AuthScreen.tsx
src/public/components/ChatbotInterface.tsx
src/public/components/Questionnaire.tsx
src/public/hooks/useAuth.ts
src/public/hooks/useNotification.tsx
src/public/index.css
src/public/index.html
src/public/main.tsx
src/public/tsconfig.json
src/routes/admin.ts
src/routes/agents.ts
src/routes/auth.ts
src/routes/projects.ts
src/types/index.ts
SUPABASE_SETUP.md
tsconfig.json
tsconfig.node.json
vite.config.ts
```

### Dependencies

- package.json: @anthropic-ai/sdk@^0.24.3, @letta-ai/letta-client@^0.0.68665, @supabase/supabase-js@^2.39.0, @types/bcryptjs@^2.4.6, @types/cors@^2.8.17, @types/express@^4.17.21, @types/jsonwebtoken@^9.0.5, @types/node@^20.10.5, @types/react@^19.2.2, @types/react-dom@^19.2.2, @types/uuid@^9.0.7, @typescript-eslint/eslint-plugin@^6.15.0, @typescript-eslint/parser@^6.15.0, @vitejs/plugin-react@^5.1.0, bcryptjs@^2.4.3, cors@^2.8.5, dotenv@^16.3.1, eslint@^8.56.0, express@^4.18.2, helmet@^7.1.0, jsonwebtoken@^9.0.2, react@^19.2.0, react-dom@^19.2.0, tsx@^4.6.2, typescript@^5.3.3, uuid@^9.0.1, vite@^7.1.12, zod@^3.22.4

### Recent commits (newest first)

- finish
- Merge pull request #4 from tupdaily/frontend-3
- frontend save
- Merge pull request #3 from tupdaily/react-migration
- not working MCP integration
- fixed agent
- Merge pull request #2 from tupdaily/react-migration
- add archival search
- UI project creation
- adding projects to users
- migrate to react
- fix login
- fix querying agent
- fixing query
- add project skeleton
- split for branching
- fixed agent creation
- old agent creation
- Merge pull request #1 from tupdaily/frontend
- rebasing

## Key source files (fetched from GitHub, selected and truncated for size)

### SUPABASE_SETUP.md

```markdown
# Supabase Setup Instructions

This application has been migrated from SQLite to Supabase. Follow these steps to set up your Supabase database.

## 1. Create a Supabase Project

1. Go to [supabase.com](https://supabase.com) and sign up/sign in
2. Click "New Project"
3. Choose your organization and enter project details:
   - Name: `hive-ai-team` (or your preferred name)
   - Database Password: Choose a strong password
   - Region: Choose the closest region to your users
4. Click "Create new project"
5. Wait for the project to be set up (this may take a few minutes)

## 2. Get Your Supabase Credentials

1. In your Supabase dashboard, go to **Settings** → **API**
2. Copy the following values:
   - **Project URL** (starts with `https://`)
   - **anon public** key (starts with `eyJ`)
   - **service_role** key (starts with `eyJ`)

## 3. Set Up Environment Variables

1. Copy `env.example` to `.env`:
   ```bash
   cp env.example .env
   ```

2. Update your `.env` file with your Supabase credentials:
   ```env
   # Supabase Database
   SUPABASE_URL=https://your-project-id.supabase.co
   SUPABASE_ANON_KEY=your-anon-key-here
   SUPABASE_SERVICE_ROLE_KEY=your-service-role-key-here
   
   # JWT Secret - Use a long, random, secure string for production
   JWT_SECRET=your-super-secret-jwt-key-here-change-this-in-production
   
   # Server
   PORT=3001
   NODE_ENV=development
   
   # Claude AI Configuration
   ANTHROPIC_API_KEY=your-anthropic-api-key-here
   ```

## 4. Create Database Tables

1. In your Supabase dashboard, go to **SQL Editor**
2. Click "New Query"
3. Copy and paste the contents of `src/database/supabase-schema.sql`
4. Click "Run" to execute the SQL and create all tables

## 5. Install Dependencies

```bash
npm install
```

## 6. Start the Application

```bash
npm run dev
```

## Database Schema

The following tables will be created:

- **users**: User accounts with authentication and memory block references
- **agents**: AI agents belonging to users
- **projects**: Project management
- **project_members**: Many-to-many relationship between projects and agents
- **memory_blocks**: Shared and individual memory storage

### Key Changes in the New Memory System:

1. **User Memory Blocks**: Each user now has a dedicated memory block stored in Supabase with their user ID/email as the label
2. **Agent Creation**: When creating an agent, users provide a description of what they want the agent to do
3. **Simplified Agent Queries**: Agents now only have a simple query method that uses Letta's message API
4. **Persona Integration**: Agent personas now include the user's description of what they want the agent to do

## Security Notes

- The `service_role` key has full access to your database - keep it secure
- The `anon` key is safe to use in client-side code
- Row Level Security (RLS) is available but not enabled by default
- Consider enabling RLS for production use

## Migration from SQLite

If you have existing data in SQLite:

1. Export your data fro
[truncated — 379 more characters]
```

### package.json

```
{
  "name": "hive-ai-team",
  "version": "1.0.0",
  "description": "AI team application with shared memory blocks using Letta",
  "main": "dist/index.js",
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "dev:frontend": "vite",
    "build": "tsc && vite build",
    "start": "node dist/index.js",
    "lint": "eslint src/**/*.ts",
    "type-check": "tsc --noEmit"
  },
  "keywords": [
    "ai",
    "letta",
    "typescript",
    "team",
    "agents",
    "memory"
  ],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "@anthropic-ai/sdk": "^0.24.3",
    "@letta-ai/letta-client": "^0.0.68665",
    "@supabase/supabase-js": "^2.39.0",
    "@types/react": "^19.2.2",
    "@types/react-dom": "^19.2.2",
    "bcryptjs": "^2.4.3",
    "cors": "^2.8.5",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "helmet": "^7.1.0",
    "jsonwebtoken": "^9.0.2",
    "react": "^19.2.0",
    "react-dom": "^19.2.0",
    "uuid": "^9.0.1",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@types/bcryptjs": "^2.4.6",
    "@types/cors": "^2.8.17",
    "@types/express": "^4.17.21",
    "@types/jsonwebtoken": "^9.0.5",
    "@types/node": "^20.10.5",
    "@types/uuid": "^9.0.7",
    "@typescript-eslint/eslint-plugin": "^6.15.0",
    "@typescript-eslint/parser": "^6.15.0",
    "@vitejs/plugin-react": "^5.1.0",
    "eslint": "^8.56.0",
    "tsx": "^4.6.2",
    "typescript": "^5.3.3",
    "vite": "^7.1.12"
  }
}

```

### src/index.ts

```typescript
import { App } from './app';

const PORT = process.env.PORT || 3001;

async function startServer() {
  try {
    const app = new App();
    await app.initialize();

    const server = app.getApp().listen(PORT, () => {
      console.log(`🚀 Server running on port ${PORT}`);
      console.log(`📊 Health check: http://localhost:${PORT}/health`);
      console.log(`🔐 Auth endpoints: http://localhost:${PORT}/api/auth`);
      console.log(`🤖 Agent endpoints: http://localhost:${PORT}/api/agents`);
      console.log(`👑 Admin endpoints: http://localhost:${PORT}/api/admin`);
    });

    // Graceful shutdown
    process.on('SIGTERM', () => {
      console.log('SIGTERM received, shutting down gracefully');
      server.close(() => {
        app.close();
        process.exit(0);
      });
    });

    process.on('SIGINT', () => {
      console.log('SIGINT received, shutting down gracefully');
      server.close(() => {
        app.close();
        process.exit(0);
      });
    });

  } catch (error) {
    console.error('Failed to start server:', error);
    process.exit(1);
  }
}

startServer();

```

### src/app.ts

```typescript
import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import dotenv from 'dotenv';
import { Database } from './database/connection';
import { AuthService } from './auth/auth';
import { AgentManager } from './ai/agentManager';
import { createAuthRoutes } from './routes/auth';
import { createAgentRoutes } from './routes/agents';
import { createAdminRoutes } from './routes/admin';
import { createProjectRoutes } from './routes/projects';

// Load environment variables
dotenv.config();

export class App {
  private app: express.Application;
  private db: Database;
  private authService: AuthService;
  private agentManager: AgentManager;

  constructor() {
    this.app = express();
    
    // Initialize Supabase database
    const supabaseUrl = process.env.SUPABASE_URL;
    const supabaseKey = process.env.SUPABASE_ANON_KEY;
    
    if (!supabaseUrl || !supabaseKey) {
      throw new Error('Missing required Supabase environment variables: SUPABASE_URL and SUPABASE_ANON_KEY');
    }
    
    this.db = new Database(supabaseUrl, supabaseKey);
    this.authService = new AuthService(this.db, process.env.JWT_SECRET || 'fallback-secret');
    this.agentManager = new AgentManager(this.db);
    
    this.setupMiddleware();
    this.setupRoutes();
  }

  private setupMiddleware(): void {
    // Security middleware
    this.app.use(helmet());
    this.app.use(cors({
      origin: process.env.NODE_ENV === 'production' ? false : true,
      credentials: true
    }));

    // Body parsing middleware
    this.app.use(express.json({ limit: '10mb' }));
    this.app.use(express.urlencoded({ extended: true }));

    // Serve static files
    this.app.use(express.static('src/public'));

    // Request logging
    this.app.use((req, res, next) => {
      console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
      next();
    });
  }

  private setupRoutes(): void {
    // Health check
    this.app.get('/health', (req, res) => {
      res.json({ status: 'ok', timestamp: new Date().toISOString() });
    });

    // API routes
    this.app.use('/api/auth', createAuthRoutes(this.authService, this.db, this.agentManager));
    this.app.use('/api/agents', createAgentRoutes(this.agentManager, this.authService));
    this.app.use('/api/admin', createAdminRoutes(this.db, this.agentManager, this.authService));
    this.app.use('/api/projects', createProjectRoutes(this.db, this.authService, this.agentManager));

    // Serve the main app
    this.app.get('/', (req, res) => {
      res.sendFile('index.html', { root: 'src/public' });
    });

    // 404 handler
    this.app.use('*', (req, res) => {
      res.status(404).json({ error: 'Route not found' });
    });

    // Error handler
    this.app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
      console.error('Error:', err);
      res.status(500).json({ error: 'Internal server error' });
    });
  }

  async initialize(): Promise<void> {
    try {
      // Initialize any required services here
      console.log('Application initialized successfully');
    } catch (error) {
      console.error('Failed to initialize application:', error);
      throw error;
    }
  }

  getApp(): express.Application {
    return this.app;
  }

  async close(): Promise<void> {
    this.db.close();
  }
}

```

### src/public/main.tsx

```typescript
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

```

### src/types/index.ts

```typescript
export interface User {
  id: string;
  email: string;
  name: string;
  role: 'admin' | 'employee';
  description?: string;
  memoryBlockId?: string;
  createdAt: Date;
  updatedAt: Date;
}

export interface Agent {
  id: string;
  userId: string;
  name: string;
  personality: string;
  workPreferences: string[];
  lettaAgentId?: string;
  isActive: boolean;
  createdAt: Date;
  updatedAt: Date;
}

export interface Project {
  id: string;
  name: string;
  description: string;
  status: 'active' | 'completed' | 'paused';
  memoryBlockId?: string; // Add this line
  createdAt: Date;
  updatedAt: Date;
}

export interface ProjectMember {
  id: string;
  projectId: string;
  agentId: string;
  role: 'lead' | 'member';
  joinedAt: Date;
}

export interface MemoryBlock {
  id: string;
  type: 'shared' | 'individual';
  agentId?: string; // Only for individual memory blocks
  content: string;
  metadata: Record<string, any>;
  createdAt: Date;
  updatedAt: Date;
}

export interface QueryRequest {
  userId: string;
  query: string;
  context?: {
    projectId?: string;
    agentId?: string;
  };
}

export interface QueryResponse {
  response: string;
  sources: string[];
  agentId: string;
  timestamp: Date;
}

export interface AdminStats {
  totalUsers: number;
  totalAgents: number;
  activeProjects: number;
  totalMemoryBlocks: number;
}

```

### src/public/App.tsx

```typescript
import React, { useState, useEffect } from 'react'
import AuthScreen from './components/AuthScreen'
import Questionnaire from './components/Questionnaire'
import ChatbotInterface from './components/ChatbotInterface'
import AdminConsole from './components/AdminConsole'
import { useAuth } from './hooks/useAuth'
import { useNotification } from './hooks/useNotification'

function App() {
  const { user, token, login, register, logout, updateDescription } = useAuth()
  const { showSuccess, showError, NotificationContainer } = useNotification()
  const [showQuestionnaire, setShowQuestionnaire] = useState(false)
  const [showAdminConsole, setShowAdminConsole] = useState(false)

  useEffect(() => {
    if (user && !user.description) {
      setShowQuestionnaire(true)
    }
  }, [user])

  const handleQuestionnaireSubmit = async (description: string) => {
    try {
      await updateDescription(description)
      showSuccess('Questionnaire submitted successfully!')
      setShowQuestionnaire(false)
    } catch (error) {
      showError('Failed to submit questionnaire. Please try again.')
    }
  }

  if (!user) {
    return (
      <AuthScreen 
        onLogin={login}
        onRegister={register}
        showError={showError}
      />
    )
  }

  if (showQuestionnaire) {
    return (
      <Questionnaire 
        onSubmit={handleQuestionnaireSubmit}
        showError={showError}
      />
    )
  }

  if (!token) return null

  return (
    <>
      <ChatbotInterface 
        user={user}
        token={token}
        onLogout={logout}
        onShowAdminConsole={() => setShowAdminConsole(true)}
      />
      
      {showAdminConsole && (
        <AdminConsole 
          onClose={() => setShowAdminConsole(false)}
          token={token}
          showSuccess={showSuccess}
          showError={showError}
        />
      )}
      
      <NotificationContainer />
    </>
  )
}

export default App

```

### vite.config.ts

```typescript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  root: 'src/public',
  build: {
    outDir: '../../dist/public',
    emptyOutDir: true
  },
  server: {
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://localhost:3001',
        changeOrigin: true
      }
    }
  }
})

```

### src/public/index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hive AI Team</title>
    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
</head>
<body class="honeycomb-bg honeycomb-pattern min-h-screen font-inter">
    <!-- The root div will hold the app's content -->
    <div id="root"></div>

    <!-- Include your main TypeScript file here -->
    <script type="module" src="/main.tsx"></script>
</body>
</html>

```

### src/middleware/auth.ts

```typescript
import { Request, Response, NextFunction } from 'express';
import { AuthService } from '../auth/auth';

export interface AuthenticatedRequest extends Request {
  user?: {
    userId: string;
    role: string;
  };
  body: any;
  params: any;
  headers: any;
}

export const authenticateToken = (authService: AuthService) => {
  return async (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];

    if (!token) {
      return res.status(401).json({ error: 'Access token required' });
    }

    const decoded = await authService.verifyToken(token);
    if (!decoded) {
      return res.status(403).json({ error: 'Invalid or expired token' });
    }

    req.user = decoded;
    next();
  };
};

export const requireAdmin = (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
  if (req.user?.role !== 'admin') {
    return res.status(403).json({ error: 'Admin access required' });
  }
  next();
};

export const requireEmployee = (req: AuthenticatedRequest, res: Response, next: NextFunction) => {
  if (!req.user || (req.user.role !== 'admin' && req.user.role !== 'employee')) {
    return res.status(403).json({ error: 'Employee access required' });
  }
  next();
};

```

[16 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]