# PROMPT 01 — Project Setup & Module Scaffold
## Prerequisites: None — this is the first prompt

---

## Your Task
Scaffold the complete Angular 20+ `CollabSpace` feature module inside an existing
enterprise Angular application. Read `@specs/stack_context.md` for all conventions.

---

## 1. Install Dependencies

Add to `package.json` and run install:
```json
{
  "@microsoft/signalr": "^8.0.0",
  "@angular/cdk": "^20.0.0",
  "date-fns": "^3.0.0",
  "uuid": "^9.0.0",
  "@types/uuid": "^9.0.0"
}
```

---

## 2. Create This Exact Folder Structure

```
src/app/modules/collaboration/
│
├── index.ts                          ← Public API — ONLY exports for other modules
├── collaboration.routes.ts           ← Lazy route definitions
│
├── core/
│   ├── enums/
│   │   └── collab.enums.ts
│   ├── models/
│   │   ├── session.model.ts
│   │   ├── participant.model.ts
│   │   ├── invite.model.ts
│   │   ├── hub-payloads.model.ts
│   │   ├── collab-config.model.ts
│   │   ├── collab-bridge.model.ts
│   │   └── index.ts
│   ├── constants/
│   │   ├── collab.constants.ts
│   │   └── collab.labels.ts
│   ├── services/
│   │   ├── collab-hub.service.ts
│   │   ├── collab-session.service.ts
│   │   ├── collab-cobrowse.service.ts
│   │   ├── collab-invite.service.ts
│   │   ├── collab-config.service.ts
│   │   └── collab-bridge.service.ts
│   └── state/
│       ├── session.state.ts
│       ├── participant.state.ts
│       ├── ui.state.ts
│       └── index.ts
│
├── components/
│   ├── toolbar/
│   │   ├── collab-toolbar.component.ts
│   │   ├── collab-toolbar.component.html
│   │   └── collab-toolbar.component.scss
│   ├── session-card/
│   │   ├── session-card.component.ts
│   │   └── session-card.component.html
│   ├── participant-panel/
│   │   ├── participant-panel.component.ts
│   │   └── participant-panel.component.html
│   ├── chat-panel/
│   │   ├── chat-panel.component.ts
│   │   └── chat-panel.component.html
│   ├── cursor-overlay/
│   │   ├── cursor-overlay.component.ts
│   │   └── cursor-overlay.component.html
│   ├── detail-panel/
│   │   ├── detail-panel.component.ts
│   │   └── detail-panel.component.html
│   └── invite-modal/
│       ├── invite-modal.component.ts
│       └── invite-modal.component.html
│
├── pages/
│   ├── dashboard/
│   │   ├── collab-dashboard.component.ts
│   │   └── collab-dashboard.component.html
│   ├── session-create/
│   │   ├── session-create.component.ts
│   │   └── session-create.component.html
│   ├── join-via-link/
│   │   ├── join-via-link.component.ts
│   │   └── join-via-link.component.html
│   └── config/
│       ├── collab-config.component.ts
│       └── collab-config.component.html
│
└── shared/
    ├── pipes/
    │   ├── elapsed-time.pipe.ts
    │   └── session-status-label.pipe.ts
    └── directives/
        ├── collab-view-only.directive.ts
        └── collab-context.directive.ts
```

---

## 3. Generate These Files With Real Content

### `core/constants/collab.constants.ts`
```typescript
// Generate with these exact values:
export const COLLAB_HUB_URL = '/hubs/collab';
export const COLLAB_API_BASE = '/api/collab';
export const COLLAB_HEARTBEAT_INTERVAL_MS = 15_000;
export const COLLAB_CURSOR_THROTTLE_MS = 60;
export const COLLAB_FORM_DEBOUNCE_MS = 300;
export const COLLAB_MAX_CHAT_LENGTH = 1000;
export const COLLAB_SESSION_CODE_PATTERN = /^[A-Z]{2}-[0-9]{4}$/;
export const COLLAB_CURSOR_COLORS: readonly string[] = [
  '#E53E3E', '#3182CE', '#38A169', '#805AD5',
  '#DD6B20', '#D69E2E', '#00B5D8', '#D53F8C',
  '#319795', '#744210',
] as const;
export const COLLAB_MAX_CHAT_HISTORY = 200;
```

### `core/constants/collab.labels.ts`
```typescript
// All UI strings in one place (i18n-ready)
// Generate labels for: session statuses, roles, modes, error messages,
// button labels, panel titles, toast messages, empty states
// Example structure:
export const COLLAB_LABELS = {
  roles: {
    host: 'Host',
    presenter: 'Presenter',
    coEditor: 'Co-Editor',
    viewer: 'Viewer',
  },
  status: { ... },
  mode: { ... },
  actions: { ... },
  errors: { ... },
  empty: { ... },
} as const;
```

### `collaboration.routes.ts`
```typescript
// Lazy routes:
// '' → CollabDashboardComponent (title: 'Collaboration Hub')
// 'new' → SessionCreateComponent (title: 'New Session')
// 'join/:token' → JoinViaLinkComponent (title: 'Join Session')
// 'config' → CollabConfigComponent (title: 'Configuration', data: { requiresRole: 'CollabAdmin' })
// '**' → redirect to ''
//
// All components must be lazy-loaded via dynamic import()
// Use withComponentInputBinding() compatible route params
```

### `index.ts` — Public barrel (STRICT — only these exports)
```typescript
// Export ONLY:
export { CollabBridgeService } from './core/services/collab-bridge.service';
export type { CollabContext, FieldChange, ICollabBridgeService } from './core/models/collab-bridge.model';
export { CollabToolbarComponent } from './components/toolbar/collab-toolbar.component';
export { CollabViewOnlyDirective } from './shared/directives/collab-view-only.directive';
export { COLLABORATION_ROUTES } from './collaboration.routes';
export { provideCollaboration } from './provide-collaboration';
```

### `provide-collaboration.ts`
```typescript
// Generate provideCollaboration() — an EnvironmentProviders function
// Called in app.config.ts to register all services
// Accepts optional CollabModuleConfig:
interface CollabModuleConfig {
  hubUrl?: string;          // override COLLAB_HUB_URL
  apiBaseUrl?: string;      // override COLLAB_API_BASE
  logLevel?: 'none' | 'warning' | 'info' | 'debug';
}
// Uses InjectionToken COLLAB_CONFIG for config
// Provides: all services (they are providedIn:'root' already, this is for config)
```

### `shared/pipes/elapsed-time.pipe.ts`
```typescript
// Pure pipe: transforms Date | null into elapsed string
// Examples: "just now" | "2m 14s" | "1h 23m" | "2 days ago"
// Updates automatically — pipe is pure but component using it
// should use interval to trigger re-evaluation
```

### `shared/directives/collab-view-only.directive.ts`
```typescript
// Attribute directive: [collabViewOnly]
// When applied to any form control/input:
//   - If session is active AND user does NOT have control → disables the element
//   - If no session OR user has control → element works normally
//   - Uses HostBinding('disabled') and HostBinding('class.collab-readonly')
//   - Uses effect() to react to CollabBridgeService signals
// Inject: CollabBridgeService
```

---

## 4. Add tsconfig Path Alias

In `tsconfig.json` `compilerOptions.paths`, add:
```json
"@collab/*": ["src/app/modules/collaboration/*"]
```

---

## 5. Scaffold All Other Files as Empty-but-Valid

For every `.ts` file not fully specified above, generate the minimal valid shell:
- Correct class/interface name
- Correct `standalone: true` and `@Injectable` decorators
- Correct imports block
- `// TODO: implemented in prompt XX` comment
- No broken imports

---

## Verification Checklist
After generating, confirm:
- [ ] `ng build` compiles with zero errors
- [ ] No circular dependencies between files
- [ ] `index.ts` only exports the listed items
- [ ] All components have `standalone: true` and `ChangeDetectionStrategy.OnPush`
- [ ] All services have `providedIn: 'root'`
