From 281d4bd2799dc3be697443034cb8de5d1356317d Mon Sep 17 00:00:00 2001 From: kuyacarlo <106532351+kuyacarlo@users.noreply.github.com> Date: Sat, 25 Jul 2026 11:31:21 +0800 Subject: [PATCH] docs: sync README and VitePress with MVP monorepo reality (#19) Align package layout, run instructions, fixture-backed data, and three Vercel projects; drop Next 14 / deploy.yml / invented API myths. Co-authored-by: Cursor --- README.md | 362 +++----- apps/docs/.vitepress/content.ts | 4 +- apps/docs/website/dev/api/authentication.md | 497 +---------- apps/docs/website/dev/api/overview.md | 587 ++----------- apps/docs/website/dev/api/user-management.md | 838 +------------------ apps/docs/website/dev/nextjs.md | 60 +- apps/docs/website/dev/overview.md | 38 + apps/docs/website/dev/supabase.md | 164 +--- apps/docs/website/guide/configuration.md | 369 +------- apps/docs/website/guide/deployment.md | 50 ++ apps/docs/website/guide/getting-started.md | 120 ++- apps/docs/website/guide/installation.md | 198 ++--- apps/docs/website/guide/introduction.md | 123 +-- apps/docs/website/guide/overview.md | 175 +--- apps/docs/website/index.md | 6 +- doc/DEPLOYMENT.md | 331 +++----- docs/handoffs/2026-07-25-docs-sync.md | 29 +- docs/handoffs/README.md | 20 +- docs/mvp/README.md | 53 +- 19 files changed, 767 insertions(+), 3257 deletions(-) create mode 100644 apps/docs/website/guide/deployment.md diff --git a/README.md b/README.md index adb5d9f..078d5a0 100644 --- a/README.md +++ b/README.md @@ -3,311 +3,157 @@ [![CI](https://github.com/4sightorg/worksight/workflows/CI/badge.svg)](https://github.com/4sightorg/worksight/actions) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -WorkSight is an employee well-being analytics platform built with Next.js and -Supabase. This monorepo contains the web application, documentation, and shared -packages. +WorkSight is an employee well-being analytics platform. This **pnpm + +Turborepo** monorepo ships a Next.js web app, a NestJS API, VitePress docs, and +shared packages β€” notably `@worksight/common` (types, fixtures, lookup utils). -## πŸ—οΈ Project Structure +**MVP note:** dashboard and API data for the current slice come from +`@worksight/common` fixtures, not live Supabase persistence. Supabase remains +optional for web auth / online mode. + +## Project structure ```text worksight/ β”œβ”€β”€ apps/ -β”‚ β”œβ”€β”€ web/ # Next.js web application -β”‚ └── docs/ # VitePress documentation -β”œβ”€β”€ packages/ # Shared packages (future) -└── .github/ # CI/CD workflows +β”‚ β”œβ”€β”€ web/ # @worksight/web β€” Next.js 15 (App Router) +β”‚ β”œβ”€β”€ api/ # @worksight/api β€” NestJS +β”‚ └── docs/ # @worksight/docs β€” VitePress +β”œβ”€β”€ packages/ +β”‚ β”œβ”€β”€ common/ # @worksight/common β€” types, fixtures, utils +β”‚ └── assets/ # @worksight/assets +β”œβ”€β”€ doc/ # Repo guides (e.g. DEPLOYMENT.md) +β”œβ”€β”€ docs/ # MVP plan + handoffs +└── .github/ # CI workflows ``` -## πŸš€ Quick Start - -### Prerequisites +## Prerequisites -- **Node.js**: v18+ -- **pnpm**: v8+ (recommended package manager) -- **Git**: For version control +- **Node.js** `>=18` (repo engines; Node 20+ recommended) +- **pnpm** `>=9` (lockfile uses pnpm 10 β€” see `packageManager` in root + `package.json`) +- **Git** -### Installation +## Quick start ```bash -# Clone the repository git clone https://github.com/4sightorg/worksight.git cd worksight - -# Install dependencies pnpm install -# Set up environment variables +# Optional web env (offline mode works without Supabase) cp apps/web/env.example apps/web/.env.local -# Edit apps/web/.env.local with your Supabase credentials ``` -### Development +### Run apps ```bash -# Start the web application +# Build shared packages first when developing API/web against common +pnpm --filter @worksight/common build + +# Web (http://localhost:3000) pnpm dev:web +# or: pnpm --filter @worksight/web dev -# Start the documentation site +# API β€” Nest listens on PORT or 3000; use another port if web is already on 3000 +pnpm --filter @worksight/api dev +# e.g. PORT=3123 pnpm --filter @worksight/api dev + +# Docs (VitePress; default http://localhost:5173) pnpm dev:docs +# or: pnpm --filter @worksight/docs dev -# Start both applications +# All turbo `dev` tasks pnpm dev ``` -Open: - -- **Web App**: -- **Documentation**: - -## πŸ“¦ Available Scripts - -### Root Scripts +### Useful root scripts ```bash -# Development -pnpm dev # Start all applications -pnpm dev:web # Start web app only -pnpm dev:docs # Start docs only - -# Building -pnpm build # Build all applications -pnpm build:web # Build web app only -pnpm build:docs # Build docs only - -# Testing -pnpm test # Run all tests -pnpm test:web # Run web app tests -pnpm lint # Lint all code -pnpm type-check # TypeScript type checking - -# Utilities -pnpm clean # Clean all build outputs -pnpm format # Format code with Prettier +pnpm build # turbo build (all packages) +pnpm build:web # @worksight/web +pnpm build:docs # @worksight/docs +pnpm type-check # turbo type-check +pnpm lint # turbo lint +pnpm test # turbo test +pnpm format # Prettier write +pnpm format:check # Prettier check +pnpm quality # turbo quality +pnpm clean # turbo clean ``` -### Application-Specific Scripts - -```bash -# Web application (apps/web) -cd apps/web -pnpm dev # Start development server -pnpm build # Build for production -pnpm start # Start production server -pnpm test # Run tests -pnpm test:watch # Run tests in watch mode - -# Documentation (apps/docs) -cd apps/docs -pnpm dev # Start dev server -pnpm build # Build static site -pnpm preview # Preview production build -``` - -## πŸ› οΈ Technology Stack - -### Web Application (`apps/web`) - -- **Framework**: Next.js 14 (App Router) -- **Language**: TypeScript -- **Styling**: Tailwind CSS + shadcn/ui -- **Database**: Supabase (PostgreSQL) -- **Authentication**: Supabase Auth -- **State Management**: React Server Components + Client Components -- **Testing**: Jest + React Testing Library -- **Deployment**: Vercel - -### Documentation (`apps/docs`) - -- **Framework**: VitePress -- **Language**: TypeScript -- **Styling**: Default VitePress theme -- **Deployment**: GitHub Pages - -### Development Tools - -- **Package Manager**: pnpm with workspaces -- **Monorepo**: Turbo for build orchestration -- **Linting**: ESLint + Prettier -- **Type Checking**: TypeScript -- **Git Hooks**: Husky (optional) -- **CI/CD**: GitHub Actions - -## 🌍 Deployment - -### Production Environments - -- **Web Application**: [worksight.vercel.app](https://worksight.vercel.app) -- **Documentation**: [worksight.github.io](https://worksight.github.io) - -### Deployment Process - -1. **Automatic Deployment**: - - Push to `main` branch triggers production deployment - - Pull requests create preview deployments (web app only) - -2. **Manual Deployment**: - - ```bash - # Trigger GitHub Actions workflow - gh workflow run deploy.yml - ``` - -See [Deployment Guide](./apps/docs/guide/deployment.md) for detailed -instructions. - -## πŸ§ͺ Testing - -### Running Tests +Filter any package directly: ```bash -# All tests -pnpm test - -# Web application tests -pnpm test:web - -# Watch mode -pnpm test:watch - -# Coverage report -pnpm test:coverage -``` - -### Test Structure - -``` -src/__tests__/ -β”œβ”€β”€ components/ # Component tests -β”œβ”€β”€ integration/ # Integration tests -└── schemas/ # Schema validation tests -``` - -## πŸ“ Project Architecture - -### Web Application - -``` -apps/web/src/ -β”œβ”€β”€ app/ # Next.js App Router pages -β”œβ”€β”€ components/ # Reusable UI components -β”œβ”€β”€ lib/ # Utility functions -β”œβ”€β”€ hooks/ # Custom React hooks -β”œβ”€β”€ types/ # TypeScript definitions -β”œβ”€β”€ styles/ # Global styles -└── __tests__/ # Test files -``` - -### Key Features - -- **Dashboard**: Employee analytics and insights -- **Survey Builder**: Create and manage employee surveys -- **User Management**: Admin panel for user administration -- **Authentication**: Secure login with multiple providers -- **Reports**: Generate and view analytics reports - -## πŸ”§ Configuration - -### Environment Variables - -Web application requires these environment variables: - -```env -NEXT_PUBLIC_SUPABASE_URL=your-supabase-url -NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key -NEXT_PUBLIC_APP_NAME=WorkSight -NEXT_PUBLIC_APP_DESCRIPTION=Employee Well-being Analytics Platform +pnpm --filter @worksight/common build +pnpm --filter @worksight/api build +pnpm --filter @worksight/api test +pnpm --filter @worksight/docs build ``` -### Supabase Setup - -1. Create a new Supabase project -2. Set up authentication providers -3. Configure database tables and policies -4. Add environment variables to your deployment - -## 🀝 Contributing - -### Development Workflow - -1. **Fork & Clone**: Fork the repository and clone locally -2. **Branch**: Create a feature branch from `main` -3. **Develop**: Make changes and test locally -4. **Test**: Ensure all tests pass -5. **Commit**: Use conventional commit messages -6. **Pull Request**: Submit PR with clear description - -### Code Standards - -- **TypeScript**: Strict mode enabled -- **ESLint**: Follow configured rules -- **Prettier**: Auto-format on save -- **Testing**: Write tests for new features -- **Documentation**: Update docs for user-facing changes - -### Commit Convention - -``` -feat: add new survey analytics dashboard -fix: resolve authentication redirect issue -docs: update deployment guide -chore: upgrade dependencies -``` - -## πŸ“ Documentation - -- **User Guide**: [Apps Documentation](./apps/docs/) -- **API Reference**: [API Documentation](./apps/docs/api/) -- **Deployment**: [Deployment Guide](./apps/docs/guide/deployment.md) -- **Contributing**: [Contributing Guide](./apps/docs/guide/contributing.md) - -## πŸ› Troubleshooting +## Technology stack -### Common Issues +| Area | Choice | +| ----------- | --------------------------------------------------- | +| Web | Next.js 15, React 19, TypeScript, Tailwind, shadcn | +| API | NestJS (`apps/api`) | +| Shared data | `@worksight/common` types + fixtures + lookup utils | +| Auth (web) | Optional Supabase Auth; offline mode supported | +| Docs | VitePress (`apps/docs`) | +| Monorepo | pnpm workspaces + Turbo | +| CI | GitHub Actions | -1. **Build Failures**: +## MVP data layer - ```bash - # Clear cache and reinstall - pnpm clean - rm -rf node_modules - pnpm install - ``` +- **Web:** dashboard / admin / tasks views consume `@worksight/common` fixtures + (via a thin bridge such as `apps/web/src/lib/mvp-data.ts` on the wire-web + branch). +- **API:** Nest endpoints return the same fixture shapes (`EmployeeProfile`, + `Team`, `Assignment`, `Activity`). There is **no** DB/Supabase read path for + those endpoints yet. +- Fixture-backed routes (API): `GET /users`, `/users/:id`, `/users/stats`, + `/teams`, `/teams/:id`, `/tasks`, `/tasks/:id`, `/tasks/stats/:employeeId`, + `/activities`, plus `/`, `/ping`, `/health`. -2. **Type Errors**: +## Deployment - ```bash - # Run type checking - pnpm type-check - ``` +Three Vercel projects share the same GitHub repo. Each has its own **Root +Directory** and `vercel.json` (Vercel does **not** merge a root config with +nested ones): -3. **Test Failures**: +| App | Package | Vercel project | Root Directory | +| ----------- | ----------------- | ---------------- | -------------- | +| `apps/web` | `@worksight/web` | `worksight` | `apps/web` | +| `apps/api` | `@worksight/api` | `worksight-api` | `apps/api` | +| `apps/docs` | `@worksight/docs` | `worksight-docs` | `apps/docs` | - ```bash - # Run tests with verbose output - pnpm test --verbose - ``` +- Production branch: **`canary`** +- Install: `pnpm install --frozen-lockfile` +- Build: `pnpm --filter @worksight/ build` +- Env vars live in the **Vercel dashboard**, not in committed `vercel.json` -### Getting Help +**API on Vercel:** the Nest `main.ts` still calls `app.listen()` β€” there is no +serverless handler yet, so a Vercel deploy does not expose invocable functions. +Use **Docker** (`docker compose up -d --build`) for a working API today. -- **Issues**: [GitHub Issues](https://github.com/4sightorg/worksight/issues) -- **Discussions**: - [GitHub Discussions](https://github.com/4sightorg/worksight/discussions) -- **Documentation**: [Project Documentation](./apps/docs/) +Full setup: [doc/DEPLOYMENT.md](./doc/DEPLOYMENT.md). VitePress site: +[apps/docs](./apps/docs/). -## πŸ“„ License +## MVP / handoffs -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file -for details. +- Plan: [docs/mvp/README.md](./docs/mvp/README.md) (epic + [#14](https://github.com/4sightorg/worksight/issues/14)) +- Handoffs: [docs/handoffs/](./docs/handoffs/) β€” issues + [#15](https://github.com/4sightorg/worksight/issues/15)–[#20](https://github.com/4sightorg/worksight/issues/20) -## πŸ™ Acknowledgments +## Contributing -- [Next.js](https://nextjs.org/) - React framework -- [Supabase](https://supabase.com/) - Backend as a Service -- [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS -- [shadcn/ui](https://ui.shadcn.com/) - UI component library -- [VitePress](https://vitepress.dev/) - Documentation framework -- [Turbo](https://turbo.build/) - Monorepo build system +1. Branch from the active integration branch (MVP work stacks on + `feat/mvp-stabilize` / `canary` as directed). +2. Use conventional commits (`feat:`, `fix:`, `docs:`, …). +3. Keep type-check / lint green for touched packages. +4. Update docs when behavior or layout changes. ---- +## License -**WorkSight** - Empowering organizations with employee well-being analytics. +MIT β€” see [LICENSE](LICENSE). diff --git a/apps/docs/.vitepress/content.ts b/apps/docs/.vitepress/content.ts index d5df237..ed1c858 100644 --- a/apps/docs/.vitepress/content.ts +++ b/apps/docs/.vitepress/content.ts @@ -4,10 +4,12 @@ const mainguide = [ { text: 'Getting Started', items: [ + { text: 'Overview', link: '/guide/overview' }, { text: 'Introduction', link: '/guide/introduction' }, { text: 'Quick Start', link: '/guide/getting-started' }, { text: 'Installation', link: '/guide/installation' }, { text: 'Configuration', link: '/guide/configuration' }, + { text: 'Deployment', link: '/guide/deployment' }, ], }, { @@ -17,6 +19,7 @@ const mainguide = [ { text: 'Burnout Assessment', link: '/features/burnout-assessment' }, { text: 'Admin Dashboard', link: '/features/admin-dashboard' }, { text: 'Reporting', link: '/features/reporting' }, + { text: 'Task Management', link: '/features/task-management' }, ], }, ]; @@ -54,7 +57,6 @@ const dev = [ items: [ { text: 'Overview', link: '/dev/api/overview' }, { text: 'Authentication', link: '/dev/api/authentication' }, - { text: 'Survey Endpoints', link: '/dev/api/survey-endpoints' }, { text: 'User Management', link: '/dev/api/user-management' }, ], }, diff --git a/apps/docs/website/dev/api/authentication.md b/apps/docs/website/dev/api/authentication.md index 83bb3d1..37244da 100644 --- a/apps/docs/website/dev/api/authentication.md +++ b/apps/docs/website/dev/api/authentication.md @@ -1,494 +1,35 @@ # Authentication -The WorkSight API uses API key authentication to secure access to your -organization's data and functionality. +## Nest API (`@worksight/api`) -## API Key Management +MVP fixture routes (`/users`, `/teams`, `/tasks`, `/activities`, health) do +**not** enforce API keys or Bearer tokens. There is no Admin β€œAPI Keys” UI, no +`ws_live_…` key format, and no hosted `api.worksight.com` auth gateway in this +repo. -### Creating API Keys +When you harden the API later, document the real mechanism here β€” do not assume +the fictional key model from older drafts. -Generate API keys through the Admin Dashboard: +## Web app (`@worksight/web`) -1. Navigate to **Settings > API Keys** -2. Click **Create New API Key** -3. Configure permissions and rate limits -4. Save the generated key securely - -```typescript -interface ApiKey { - id: string; - name: string; - key: string; // Only shown once during creation - keyPrefix: string; // First 8 characters for identification - permissions: Permission[]; - rateLimit: RateLimit; - organizationId: string; - createdBy: string; - createdAt: Date; - lastUsed?: Date; - expiresAt?: Date; - active: boolean; -} -``` - -### API Key Format - -API keys follow a structured format: - -``` -ws_live_1234567890abcdef1234567890abcdef12345678 -β”‚ β”‚ β”‚ -β”‚ β”‚ └── Random key data (40 characters) -β”‚ └─────── Environment (live/test) -└─────────── Prefix (ws = WorkSight) -``` - -## Authentication Methods - -### Bearer Token Authentication - -Include your API key in the `Authorization` header: - -```bash -curl -H "Authorization: Bearer ws_live_1234567890abcdef..." \ - https://api.worksight.com/v1/users -``` - -```javascript -const response = await fetch('https://api.worksight.com/v1/users', { - headers: { - Authorization: 'Bearer ws_live_1234567890abcdef...', - 'Content-Type': 'application/json', - }, -}); -``` - -### Query Parameter (Not Recommended) - -For testing only, you can include the API key as a query parameter: +Optional **Supabase Auth** when offline mode is off: ```bash -curl https://api.worksight.com/v1/users?api_key=ws_live_1234567890abcdef... -``` - -::: warning Never use query parameter authentication in production. API keys in -URLs may be logged by servers, proxies, or browsers. ::: - -## Permission System - -### Permission Levels - -API keys can be configured with granular permissions: - -#### Read Permissions - -- `users:read` - View user information -- `surveys:read` - Access survey data -- `assessments:read` - View assessment results -- `reports:read` - Access reports and analytics -- `organization:read` - View organizational data - -#### Write Permissions - -- `users:write` - Create and update users -- `surveys:write` - Create and manage surveys -- `assessments:write` - Submit assessment responses -- `reports:write` - Generate custom reports -- `organization:write` - Modify organizational settings - -#### Admin Permissions - -- `users:admin` - Full user management including deletion -- `organization:admin` - Complete organizational control -- `api:admin` - Manage API keys and webhooks -- `billing:admin` - Access billing and subscription data - -### Permission Examples - -```json -{ - "name": "HR Dashboard Integration", - "permissions": [ - "users:read", - "assessments:read", - "reports:read", - "reports:write" - ] -} -``` - -```json -{ - "name": "Survey Management Bot", - "permissions": ["surveys:read", "surveys:write", "users:read"] -} -``` - -## Rate Limiting - -### Rate Limit Headers - -Every API response includes rate limit information: - -```http -HTTP/1.1 200 OK -X-RateLimit-Limit: 1000 -X-RateLimit-Remaining: 999 -X-RateLimit-Reset: 1640995200 -X-RateLimit-Window: 3600 -``` - -- `X-RateLimit-Limit`: Maximum requests allowed in the time window -- `X-RateLimit-Remaining`: Requests remaining in current window -- `X-RateLimit-Reset`: Unix timestamp when the rate limit resets -- `X-RateLimit-Window`: Time window in seconds - -### Rate Limit Tiers - -#### Standard Tier - -- 1,000 requests per hour -- 10,000 requests per day -- Suitable for small integrations - -#### Professional Tier - -- 5,000 requests per hour -- 50,000 requests per day -- Ideal for medium-scale applications - -#### Enterprise Tier - -- 10,000 requests per hour -- 100,000 requests per day -- Custom limits available - -### Handling Rate Limits - -When you exceed rate limits, you'll receive a `429 Too Many Requests` response: - -```json -{ - "success": false, - "error": { - "code": "RATE_LIMIT_EXCEEDED", - "message": "Rate limit exceeded. Try again in 3600 seconds.", - "details": { - "limit": 1000, - "window": 3600, - "retryAfter": 3600 - } - } -} -``` - -#### Best Practices for Rate Limiting - -```javascript -async function makeApiRequest(url, options) { - try { - const response = await fetch(url, options); - - if (response.status === 429) { - const retryAfter = response.headers.get('Retry-After'); - console.log(`Rate limited. Retry after ${retryAfter} seconds`); - - // Exponential backoff - await new Promise((resolve) => - setTimeout(resolve, (retryAfter || 60) * 1000) - ); - - return makeApiRequest(url, options); // Retry - } - - return response; - } catch (error) { - console.error('API request failed:', error); - throw error; - } -} +NEXT_PUBLIC_IS_OFFLINE=false +NEXT_PUBLIC_SUPABASE_URL=… +NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=… ``` -## Security Best Practices - -### API Key Storage - -#### βœ… Secure Storage +For local / fixture demos: ```bash -# Environment variables -export WORKSIGHT_API_KEY="ws_live_1234567890abcdef..." - -# Configuration files (not in version control) -echo "ws_live_1234567890abcdef..." > /etc/myapp/worksight.key -chmod 600 /etc/myapp/worksight.key +NEXT_PUBLIC_IS_OFFLINE=true +IS_OFFLINE=true ``` -#### ❌ Insecure Storage - -```javascript -// Never hardcode API keys -const API_KEY = 'ws_live_1234567890abcdef...'; // BAD! - -// Never commit keys to version control -const config = { - apiKey: 'ws_live_1234567890abcdef...', // BAD! -}; -``` - -### Key Rotation - -Regularly rotate your API keys: - -1. **Generate a new key** in the Admin Dashboard -2. **Update your applications** with the new key -3. **Test thoroughly** to ensure everything works -4. **Deactivate the old key** after successful migration - -### Monitoring - -Monitor API key usage for security: - -- **Unusual traffic patterns** - Sudden spikes in requests -- **Geographic anomalies** - Requests from unexpected locations -- **Permission escalation** - Attempts to access unauthorized resources -- **Error patterns** - High rates of authentication failures - -## Environment Management - -### Test vs Production Keys - -Use different API keys for different environments: - -```typescript -const API_CONFIG = { - development: { - baseUrl: 'http://localhost:3000/api/v1', - apiKey: process.env.WORKSIGHT_TEST_API_KEY, - }, - staging: { - baseUrl: 'https://staging-api.worksight.com/v1', - apiKey: process.env.WORKSIGHT_STAGING_API_KEY, - }, - production: { - baseUrl: 'https://api.worksight.com/v1', - apiKey: process.env.WORKSIGHT_LIVE_API_KEY, - }, -}; -``` - -### Key Prefixes - -WorkSight uses key prefixes to identify environments: - -- `ws_test_` - Test/development environment -- `ws_live_` - Production environment - -## Authentication Errors - -### Common Error Responses - -#### Missing API Key - -```http -HTTP/1.1 401 Unauthorized -``` - -```json -{ - "success": false, - "error": { - "code": "AUTHENTICATION_REQUIRED", - "message": "API key is required for this endpoint" - } -} -``` - -#### Invalid API Key - -```http -HTTP/1.1 401 Unauthorized -``` - -```json -{ - "success": false, - "error": { - "code": "INVALID_API_KEY", - "message": "The provided API key is invalid or has been revoked" - } -} -``` - -#### Insufficient Permissions - -```http -HTTP/1.1 403 Forbidden -``` - -```json -{ - "success": false, - "error": { - "code": "INSUFFICIENT_PERMISSIONS", - "message": "API key does not have permission to access this resource", - "details": { - "required": "users:write", - "provided": ["users:read", "surveys:read"] - } - } -} -``` - -#### Expired API Key - -```http -HTTP/1.1 401 Unauthorized -``` - -```json -{ - "success": false, - "error": { - "code": "API_KEY_EXPIRED", - "message": "API key has expired", - "details": { - "expiredAt": "2024-01-15T00:00:00Z" - } - } -} -``` - -## Advanced Authentication - -### IP Allowlisting - -Restrict API key usage to specific IP addresses: - -```json -{ - "name": "Production Server", - "permissions": ["users:read", "assessments:write"], - "ipAllowlist": ["203.0.113.1", "203.0.113.0/24"] -} -``` - -### Webhook Authentication - -Secure webhook endpoints with signature verification: - -```javascript -const crypto = require('crypto'); - -function verifyWebhookSignature(payload, signature, secret) { - const expectedSignature = crypto - .createHmac('sha256', secret) - .update(payload) - .digest('hex'); - - return crypto.timingSafeEqual( - Buffer.from(signature, 'hex'), - Buffer.from(expectedSignature, 'hex') - ); -} - -// Express.js middleware -app.use('/webhooks/worksight', (req, res, next) => { - const signature = req.headers['x-worksight-signature']; - const isValid = verifyWebhookSignature( - req.body, - signature, - process.env.WEBHOOK_SECRET - ); - - if (!isValid) { - return res.status(401).json({ error: 'Invalid signature' }); - } - - next(); -}); -``` - -### Session-based Authentication (Web Applications) - -For web applications, use session-based authentication: - -```javascript -// Exchange API key for session token -const session = await fetch('/api/auth/session', { - method: 'POST', - headers: { - Authorization: 'Bearer ws_live_1234567890abcdef...', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - expiresIn: '1h', - }), -}); - -const { token } = await session.json(); - -// Use session token for subsequent requests -const response = await fetch('/api/users', { - headers: { - Authorization: `Bearer ${token}`, - }, -}); -``` - -## Testing Authentication - -### Test API Key - -Use the test environment to validate your authentication setup: - -```bash -curl -H "Authorization: Bearer ws_test_1234567890abcdef..." \ - https://staging-api.worksight.com/v1/auth/test -``` - -Response: - -```json -{ - "success": true, - "data": { - "apiKey": { - "id": "key_123", - "name": "Test Key", - "permissions": ["users:read", "surveys:read"], - "organization": "org_456" - }, - "user": { - "id": "user_789", - "email": "api@company.com", - "role": "api_user" - } - } -} -``` - -### Authentication Health Check - -```bash -# Check if your API key is working -curl -H "Authorization: Bearer YOUR_API_KEY" \ - https://api.worksight.com/v1/health -``` - -## Migration Guide - -### Upgrading from API v1 to v2 - -When migrating to newer API versions: - -1. **Generate new API keys** with v2 permissions -2. **Update base URLs** to include version -3. **Review breaking changes** in the changelog -4. **Test thoroughly** before switching production traffic +See `apps/web/env.example` and [Configuration](/guide/configuration). -### Deprecation Timeline +## Related -- **v1**: Supported until December 2024 -- **v2**: Current stable version -- **v3**: Beta, general availability Q2 2024 +- [API overview](./overview.md) +- [User management](./user-management.md) diff --git a/apps/docs/website/dev/api/overview.md b/apps/docs/website/dev/api/overview.md index f38fdd6..3cb3269 100644 --- a/apps/docs/website/dev/api/overview.md +++ b/apps/docs/website/dev/api/overview.md @@ -1,556 +1,79 @@ # API Overview -The WorkSight API provides comprehensive access to all platform features through -RESTful endpoints, enabling seamless integration with your existing systems and -custom applications. +The NestJS app in `apps/api` (`@worksight/api`) exposes HTTP endpoints for the +MVP. Responses use shapes from `@worksight/common` and are **fixture-backed** β€” +not loaded from Supabase or another database yet. -## Getting Started +## Base URL -### Base URL +| Environment | URL | +| ----------- | --------------------------------------------------------------------------- | +| Local | `http://localhost:3123` (or your `PORT`) | +| Docker | per `docker-compose.yml` / nginx | +| Vercel | project `worksight-api` builds `dist/` only β€” **no serverless handler yet** | -``` -Production: https://api.worksight.com/v1 -Staging: https://staging-api.worksight.com/v1 -Development: http://localhost:3000/api/v1 -``` - -### Authentication - -WorkSight API uses API keys for authentication. Include your API key in the -`Authorization` header: - -```bash -curl -H "Authorization: Bearer YOUR_API_KEY" \ - https://api.worksight.com/v1/users -``` - -### Quick Start - -1. **Get your API key** from the Admin Dashboard -2. **Make your first request** to test connectivity -3. **Explore the endpoints** using our interactive documentation -4. **Integrate** with your applications - -```javascript -// Example: Get organization health metrics -const response = await fetch('https://api.worksight.com/v1/metrics/health', { - headers: { - Authorization: 'Bearer YOUR_API_KEY', - 'Content-Type': 'application/json', - }, -}); - -const healthData = await response.json(); -console.log('Organization health score:', healthData.overallScore); -``` - -## API Design Principles - -### RESTful Architecture - -- **Resource-based URLs**: Each endpoint represents a specific resource -- **HTTP Methods**: GET, POST, PUT, PATCH, DELETE for different operations -- **Status Codes**: Standard HTTP status codes for responses -- **JSON Format**: All requests and responses use JSON - -### Consistency - -- **Naming Conventions**: Consistent parameter and field naming -- **Response Structure**: Standardized response format across all endpoints -- **Error Handling**: Uniform error response structure -- **Versioning**: Clear API versioning strategy - -## Authentication & Authorization - -### API Key Management - -```typescript -interface ApiKey { - id: string; - name: string; - key: string; - permissions: Permission[]; - rateLimit: { - requestsPerMinute: number; - requestsPerDay: number; - }; - expiresAt?: Date; - lastUsed?: Date; - active: boolean; -} -``` - -### Permission Levels - -#### Read-Only Access - -- View users and organizational data -- Access reports and analytics -- Retrieve survey responses (with appropriate permissions) - -#### Read-Write Access - -- Create and update users -- Manage surveys and assessments -- Modify organizational settings - -#### Admin Access - -- Full API access -- User management -- System configuration -- Billing and subscription management - -### Rate Limiting - -```http -X-RateLimit-Limit: 1000 -X-RateLimit-Remaining: 999 -X-RateLimit-Reset: 1640995200 -``` - -Default rate limits: - -- **Standard Plan**: 1,000 requests per hour -- **Professional Plan**: 5,000 requests per hour -- **Enterprise Plan**: 10,000 requests per hour - -## Core Resources - -### Users - -Manage user accounts, profiles, and organizational relationships. - -```typescript -interface User { - id: string; - email: string; - firstName: string; - lastName: string; - role: UserRole; - department: string; - manager?: string; - startDate: Date; - status: 'active' | 'inactive' | 'pending'; - lastLogin?: Date; - createdAt: Date; - updatedAt: Date; -} -``` - -**Endpoints:** - -- `GET /users` - List all users -- `GET /users/{id}` - Get specific user -- `POST /users` - Create new user -- `PUT /users/{id}` - Update user -- `DELETE /users/{id}` - Deactivate user - -### Surveys - -Create, manage, and analyze survey data. - -```typescript -interface Survey { - id: string; - title: string; - description: string; - type: 'burnout' | 'engagement' | 'custom'; - questions: Question[]; - schedule: Schedule; - status: 'draft' | 'active' | 'completed' | 'archived'; - participantCount: number; - responseCount: number; - createdAt: Date; - updatedAt: Date; -} -``` - -**Endpoints:** - -- `GET /surveys` - List surveys -- `POST /surveys` - Create survey -- `PUT /surveys/{id}` - Update survey -- `POST /surveys/{id}/send` - Send survey to participants -- `GET /surveys/{id}/responses` - Get survey responses - -### Assessments - -Burnout assessments and well-being evaluations. - -```typescript -interface Assessment { - id: string; - userId: string; - surveyId: string; - responses: Record; - score: number; - riskLevel: 'low' | 'moderate' | 'high' | 'critical'; - completedAt: Date; - analysis: { - emotionalExhaustion: number; - depersonalization: number; - personalAccomplishment: number; - workLifeBalance: number; - }; -} -``` - -**Endpoints:** - -- `GET /assessments` - List assessments -- `POST /assessments` - Submit assessment -- `GET /assessments/{id}` - Get assessment details -- `GET /users/{userId}/assessments` - Get user's assessments - -### Reports - -Access analytics and reporting data. - -```typescript -interface Report { - id: string; - type: 'individual' | 'team' | 'organization'; - title: string; - data: any; - generatedAt: Date; - period: { - startDate: Date; - endDate: Date; - }; - format: 'json' | 'pdf' | 'excel'; -} -``` - -**Endpoints:** - -- `GET /reports` - List available reports -- `POST /reports/generate` - Generate custom report -- `GET /reports/{id}` - Get report data -- `GET /reports/{id}/download` - Download report file - -## Request/Response Format - -### Standard Response Structure - -```typescript -interface ApiResponse { - success: boolean; - data?: T; - error?: { - code: string; - message: string; - details?: any; - }; - pagination?: { - page: number; - limit: number; - total: number; - totalPages: number; - }; - meta?: { - requestId: string; - timestamp: Date; - version: string; - }; -} -``` - -### Success Response Example - -```json -{ - "success": true, - "data": { - "id": "user_123", - "email": "john.doe@company.com", - "firstName": "John", - "lastName": "Doe", - "role": "employee" - }, - "meta": { - "requestId": "req_abc123", - "timestamp": "2024-01-15T10:30:00Z", - "version": "1.0" - } -} -``` - -### Error Response Example - -```json -{ - "success": false, - "error": { - "code": "VALIDATION_ERROR", - "message": "Invalid email format", - "details": { - "field": "email", - "value": "invalid-email", - "constraint": "Must be a valid email address" - } - }, - "meta": { - "requestId": "req_xyz789", - "timestamp": "2024-01-15T10:30:00Z", - "version": "1.0" - } -} -``` - -## Pagination - -### Query Parameters - -``` -GET /users?page=1&limit=20&sort=createdAt&order=desc -``` - -- `page`: Page number (default: 1) -- `limit`: Items per page (default: 20, max: 100) -- `sort`: Sort field -- `order`: Sort direction (asc/desc) - -### Response - -```json -{ - "success": true, - "data": [...], - "pagination": { - "page": 1, - "limit": 20, - "total": 150, - "totalPages": 8, - "hasNext": true, - "hasPrev": false - } -} -``` - -## Filtering and Search - -### Query Filters - -``` -GET /users?department=Engineering&role=employee&status=active -``` - -### Search - -``` -GET /users?search=john&fields=firstName,lastName,email -``` - -### Date Ranges - -``` -GET /assessments?startDate=2024-01-01&endDate=2024-01-31 -``` - -## Webhooks +Default Nest listen port is `process.env.PORT ?? 3000`. Prefer a non-3000 port +when `@worksight/web` is already running. -### Event Types +## Authentication -```typescript -type WebhookEvent = - | 'user.created' - | 'user.updated' - | 'user.deactivated' - | 'survey.created' - | 'survey.completed' - | 'assessment.submitted' - | 'assessment.high_risk' - | 'report.generated'; -``` +MVP fixture routes do **not** require API keys. Do not assume production API-key +auth, rate-limit headers, or hosted `api.worksight.com` SDKs β€” those are not +shipped. -### Webhook Payload - -```json -{ - "event": "assessment.high_risk", - "timestamp": "2024-01-15T10:30:00Z", - "data": { - "assessmentId": "assess_123", - "userId": "user_456", - "riskLevel": "high", - "score": 75, - "previousScore": 45 - }, - "organization": { - "id": "org_789", - "name": "Acme Corp" - } -} -``` - -### Configuration - -```bash -curl -X POST https://api.worksight.com/v1/webhooks \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "url": "https://your-app.com/webhooks/worksight", - "events": ["assessment.high_risk", "survey.completed"], - "secret": "your-webhook-secret" - }' -``` +Web auth (optional Supabase) is separate from this Nest surface. -## SDKs and Libraries +## Endpoints (MVP) -### Official SDKs +### Health -#### JavaScript/TypeScript +| Method | Path | Notes | +| ------ | --------- | ------------ | +| `GET` | `/` | App root | +| `GET` | `/ping` | Liveness | +| `GET` | `/health` | Health check | -```bash -npm install apps/api-client -``` +### Users & teams -```javascript -import { WorkSightAPI } from 'apps/api-client'; +| Method | Path | Returns | +| ------ | -------------- | ------------------------------- | +| `GET` | `/users` | `EmployeeProfile[]` fixtures | +| `GET` | `/users/stats` | Aggregate role/department stats | +| `GET` | `/users/:id` | One profile (404 if missing) | +| `GET` | `/teams` | `Team[]` | +| `GET` | `/teams/:id` | One team | -const api = new WorkSightAPI({ - apiKey: 'your-api-key', - baseUrl: 'https://api.worksight.com/v1', -}); +### Tasks & activities -// Get organization health -const health = await api.metrics.getHealth(); -``` +| Method | Path | Returns | +| ------ | -------------------------- | --------------------------------------- | +| `GET` | `/tasks` | `Assignment[]` (`?employee_id=` filter) | +| `GET` | `/tasks/:id` | One assignment | +| `GET` | `/tasks/stats/:employeeId` | Per-employee task / balance stats | +| `GET` | `/activities` | `Activity[]` (optional `?employee_id=`) | -#### Python +## Quick smoke test ```bash -pip install worksight-api -``` - -```python -from worksight import WorkSightAPI +pnpm --filter @worksight/common build +pnpm --filter @worksight/api build +PORT=3123 node apps/api/dist/main.js -api = WorkSightAPI(api_key='your-api-key') - -# Get all users -users = api.users.list() +curl -s http://localhost:3123/users | head +curl -s http://localhost:3123/tasks +curl -s http://localhost:3123/health ``` -#### PHP - -```bash -composer require worksight/api-client -``` - -```php -use WorkSight\ApiClient; - -$api = new ApiClient('your-api-key'); - -// Create new survey -$survey = $api->surveys->create([ - 'title' => 'Weekly Check-in', - 'type' => 'burnout' -]); -``` - -## Error Codes - -### HTTP Status Codes - -- `200` - OK -- `201` - Created -- `204` - No Content -- `400` - Bad Request -- `401` - Unauthorized -- `403` - Forbidden -- `404` - Not Found -- `409` - Conflict -- `422` - Unprocessable Entity -- `429` - Too Many Requests -- `500` - Internal Server Error - -### Application Error Codes - -```typescript -enum ErrorCode { - VALIDATION_ERROR = 'VALIDATION_ERROR', - AUTHENTICATION_FAILED = 'AUTHENTICATION_FAILED', - INSUFFICIENT_PERMISSIONS = 'INSUFFICIENT_PERMISSIONS', - RESOURCE_NOT_FOUND = 'RESOURCE_NOT_FOUND', - DUPLICATE_RESOURCE = 'DUPLICATE_RESOURCE', - RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED', - EXTERNAL_SERVICE_ERROR = 'EXTERNAL_SERVICE_ERROR', - MAINTENANCE_MODE = 'MAINTENANCE_MODE', -} -``` - -## Best Practices - -### API Usage - -1. **Use appropriate HTTP methods** for different operations -2. **Handle rate limits** gracefully with exponential backoff -3. **Validate input data** before sending requests -4. **Cache responses** when appropriate -5. **Use webhooks** for real-time updates instead of polling - -### Security - -1. **Store API keys securely** - never expose in client-side code -2. **Use HTTPS** for all requests -3. **Validate webhook signatures** to ensure authenticity -4. **Implement proper error handling** without exposing sensitive data -5. **Monitor API usage** for unusual patterns - -### Performance - -1. **Use pagination** for large result sets -2. **Request only needed fields** using field selection -3. **Batch operations** when possible -4. **Implement caching** for frequently accessed data -5. **Use compression** for large payloads - -## Testing - -### Test Environment - -Use the staging environment for testing: - -``` -https://staging-api.worksight.com/v1 -``` - -### Postman Collection - -Download our Postman collection for easy testing: - -``` -https://api.worksight.com/docs/postman.json -``` - -### Sample Data - -The staging environment includes sample data for testing: - -- 50 test users across 5 departments -- Historical survey responses -- Generated reports and analytics - -## Support - -### Documentation - -- **Interactive API Docs**: -- **Changelog**: -- **Status Page**: - -### Contact +## Not available yet -- **Email**: -- **Slack**: #api-support in our community Slack -- **GitHub**: +- POST/PUT/DELETE mutations for users/tasks +- Survey / burnout / attendance HTTP modules (types may exist in common) +- Supabase-backed persistence for these routes +- Serverless Vercel entrypoint +- Official SDKs, webhooks, or Postman collections at `api.worksight.com` -### SLA +## Related -- **Uptime**: 99.9% guaranteed -- **Response Time**: < 200ms average -- **Support Response**: < 24 hours for standard plans, < 4 hours for enterprise +- [User management](./user-management.md) β€” users/teams detail +- [Authentication](./authentication.md) β€” web/API auth status +- Repo deployment notes: [Deployment guide](/guide/deployment) diff --git a/apps/docs/website/dev/api/user-management.md b/apps/docs/website/dev/api/user-management.md index 5b61af0..64d3332 100644 --- a/apps/docs/website/dev/api/user-management.md +++ b/apps/docs/website/dev/api/user-management.md @@ -1,838 +1,58 @@ -# User Management +# User Management (API) -The User Management API allows you to programmatically manage users within your -WorkSight organization, including creating accounts, updating profiles, managing -roles, and handling user lifecycle events. +MVP Nest routes for employees and teams. All data comes from `@worksight/common` +fixtures (`EmployeeProfile`, `Team`). -## Core User Object - -```typescript -interface User { - id: string; // Unique user identifier - email: string; // Primary email address - firstName: string; // User's first name - lastName: string; // User's last name - displayName?: string; // Optional display name - avatar?: string; // Profile image URL - role: UserRole; // User's role in the organization - department?: string; // Department or team - jobTitle?: string; // Job title - employeeId?: string; // Employee identifier - startDate?: Date; // Employment start date - status: UserStatus; // Account status - preferences: UserPreferences; // User settings and preferences - metadata: Record; // Custom fields - createdAt: Date; // Account creation timestamp - updatedAt: Date; // Last modification timestamp - lastLoginAt?: Date; // Last successful login - organizationId: string; // Organization identifier -} - -type UserRole = 'admin' | 'manager' | 'employee' | 'contractor' | 'viewer'; - -type UserStatus = 'active' | 'inactive' | 'suspended' | 'pending_invitation'; - -interface UserPreferences { - language: string; // Preferred language (ISO 639-1) - timezone: string; // Timezone (IANA format) - emailNotifications: boolean; // Email notification preference - theme: 'light' | 'dark' | 'auto'; - dashboardLayout: string[]; // Preferred dashboard widgets -} -``` - -## List Users - -Retrieve a paginated list of users in your organization. - -### Request - -```http -GET /api/v1/users -``` - -### Query Parameters - -| Parameter | Type | Description | Default | -| ------------ | ------- | ------------------------------------------ | -------- | -| `page` | integer | Page number (1-based) | `1` | -| `limit` | integer | Items per page (1-100) | `20` | -| `search` | string | Search term (name, email) | - | -| `role` | string | Filter by user role | - | -| `status` | string | Filter by user status | `active` | -| `department` | string | Filter by department | - | -| `sort` | string | Sort field (`name`, `email`, `created_at`) | `name` | -| `order` | string | Sort order (`asc`, `desc`) | `asc` | - -### Example Request - -```bash -curl -H "Authorization: Bearer YOUR_API_KEY" \ - "https://api.worksight.com/v1/users?page=1&limit=10&role=employee&status=active" -``` - -### Response - -```json -{ - "success": true, - "data": { - "users": [ - { - "id": "user_123", - "email": "john.doe@company.com", - "firstName": "John", - "lastName": "Doe", - "displayName": "John D.", - "role": "employee", - "department": "Engineering", - "jobTitle": "Software Engineer", - "status": "active", - "preferences": { - "language": "en", - "timezone": "America/New_York", - "emailNotifications": true, - "theme": "dark" - }, - "createdAt": "2024-01-15T10:30:00Z", - "updatedAt": "2024-01-20T14:22:00Z", - "lastLoginAt": "2024-01-22T09:15:00Z" - } - ], - "pagination": { - "page": 1, - "limit": 10, - "total": 156, - "totalPages": 16, - "hasNext": true, - "hasPrev": false - } - } -} -``` - -## Get User - -Retrieve detailed information about a specific user. - -### Request - -```http -GET /api/v1/users/{userId} -``` - -### Path Parameters - -| Parameter | Type | Description | -| --------- | ------ | ------------------------ | -| `userId` | string | User ID or email address | - -### Example Request - -```bash -curl -H "Authorization: Bearer YOUR_API_KEY" \ - https://api.worksight.com/v1/users/user_123 -``` - -### Response - -```json -{ - "success": true, - "data": { - "user": { - "id": "user_123", - "email": "john.doe@company.com", - "firstName": "John", - "lastName": "Doe", - "displayName": "John D.", - "avatar": "https://cdn.worksight.com/avatars/user_123.jpg", - "role": "employee", - "department": "Engineering", - "jobTitle": "Software Engineer", - "employeeId": "ENG-001", - "startDate": "2023-06-01T00:00:00Z", - "status": "active", - "preferences": { - "language": "en", - "timezone": "America/New_York", - "emailNotifications": true, - "theme": "dark", - "dashboardLayout": ["burnout-score", "recent-surveys", "team-insights"] - }, - "metadata": { - "slackId": "U01234567", - "team": "Platform Team", - "level": "Senior" - }, - "createdAt": "2023-05-15T10:30:00Z", - "updatedAt": "2024-01-20T14:22:00Z", - "lastLoginAt": "2024-01-22T09:15:00Z", - "organizationId": "org_456" - }, - "stats": { - "surveysCompleted": 12, - "assessmentScore": 7.2, - "lastAssessmentAt": "2024-01-18T16:30:00Z", - "streakDays": 5 - } - } -} -``` - -## Create User - -Create a new user account in your organization. - -### Request - -```http -POST /api/v1/users -``` - -### Request Body - -```json -{ - "email": "jane.smith@company.com", - "firstName": "Jane", - "lastName": "Smith", - "role": "employee", - "department": "Marketing", - "jobTitle": "Marketing Manager", - "employeeId": "MKT-003", - "startDate": "2024-02-01", - "sendInvitation": true, - "preferences": { - "language": "en", - "timezone": "America/Los_Angeles" - }, - "metadata": { - "team": "Growth Team", - "level": "Manager" - } -} -``` - -### Required Fields - -- `email` - Must be unique within the organization -- `firstName` - User's first name -- `lastName` - User's last name -- `role` - User role in the organization - -### Example Request - -```bash -curl -X POST \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "email": "jane.smith@company.com", - "firstName": "Jane", - "lastName": "Smith", - "role": "employee", - "department": "Marketing", - "sendInvitation": true - }' \ - https://api.worksight.com/v1/users -``` - -### Response - -```json -{ - "success": true, - "data": { - "user": { - "id": "user_456", - "email": "jane.smith@company.com", - "firstName": "Jane", - "lastName": "Smith", - "role": "employee", - "department": "Marketing", - "status": "pending_invitation", - "createdAt": "2024-01-23T10:30:00Z", - "organizationId": "org_456" - }, - "invitation": { - "id": "inv_789", - "token": "inv_tok_abcdef123456", - "expiresAt": "2024-01-30T10:30:00Z", - "inviteUrl": "https://app.worksight.com/invite/inv_tok_abcdef123456" - } - } -} -``` - -## Update User - -Update an existing user's information. - -### Request - -```http -PUT /api/v1/users/{userId} -``` - -### Request Body - -```json -{ - "firstName": "Jane", - "lastName": "Smith-Johnson", - "department": "Product Marketing", - "jobTitle": "Senior Marketing Manager", - "preferences": { - "theme": "light", - "emailNotifications": false - }, - "metadata": { - "team": "Growth Team", - "level": "Senior Manager" - } -} -``` - -### Example Request - -```bash -curl -X PUT \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "department": "Product Marketing", - "jobTitle": "Senior Marketing Manager" - }' \ - https://api.worksight.com/v1/users/user_456 -``` - -### Response - -```json -{ - "success": true, - "data": { - "user": { - "id": "user_456", - "email": "jane.smith@company.com", - "firstName": "Jane", - "lastName": "Smith-Johnson", - "department": "Product Marketing", - "jobTitle": "Senior Marketing Manager", - "status": "active", - "updatedAt": "2024-01-23T15:45:00Z" - } - } -} -``` - -## Update User Role - -Change a user's role within the organization. - -### Request - -```http -PATCH /api/v1/users/{userId}/role -``` - -### Request Body - -```json -{ - "role": "manager", - "reason": "Promotion to team lead position" -} -``` - -### Available Roles - -- `admin` - Full system access -- `manager` - Team management and reporting -- `employee` - Standard user access -- `contractor` - Limited access for contractors -- `viewer` - Read-only access - -### Example Request - -```bash -curl -X PATCH \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "role": "manager", - "reason": "Promotion to team lead position" - }' \ - https://api.worksight.com/v1/users/user_456/role -``` - -### Response - -```json -{ - "success": true, - "data": { - "user": { - "id": "user_456", - "role": "manager", - "updatedAt": "2024-01-23T16:00:00Z" - }, - "roleChange": { - "previousRole": "employee", - "newRole": "manager", - "changedBy": "user_789", - "reason": "Promotion to team lead position", - "changedAt": "2024-01-23T16:00:00Z" - } - } -} -``` - -## Update User Status - -Activate, deactivate, or suspend a user account. - -### Request - -```http -PATCH /api/v1/users/{userId}/status -``` - -### Request Body - -```json -{ - "status": "suspended", - "reason": "Policy violation", - "notifyUser": false -} -``` - -### Available Statuses - -- `active` - User can access the system -- `inactive` - User account is disabled but can be reactivated -- `suspended` - User account is temporarily suspended -- `pending_invitation` - User has been invited but hasn't activated their - account - -### Example Request - -```bash -curl -X PATCH \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "status": "inactive", - "reason": "Employee left the company", - "notifyUser": false - }' \ - https://api.worksight.com/v1/users/user_456/status -``` - -### Response - -```json -{ - "success": true, - "data": { - "user": { - "id": "user_456", - "status": "inactive", - "updatedAt": "2024-01-23T17:00:00Z" - }, - "statusChange": { - "previousStatus": "active", - "newStatus": "inactive", - "changedBy": "user_789", - "reason": "Employee left the company", - "changedAt": "2024-01-23T17:00:00Z" - } - } -} -``` - -## Delete User - -Permanently delete a user account and all associated data. - -### Request +## List employees ```http -DELETE /api/v1/users/{userId} +GET /users ``` -### Query Parameters - -| Parameter | Type | Description | Default | -| ------------------ | ------- | --------------------------- | ------- | -| `transfer_data_to` | string | User ID to transfer data to | - | -| `confirm` | boolean | Confirmation flag | `false` | - -### Example Request +Returns `EmployeeProfile[]` from the shared fixtures. ```bash -curl -X DELETE \ - -H "Authorization: Bearer YOUR_API_KEY" \ - "https://api.worksight.com/v1/users/user_456?confirm=true" -``` - -### Response - -```json -{ - "success": true, - "data": { - "deleted": true, - "userId": "user_456", - "deletedAt": "2024-01-23T18:00:00Z", - "dataRetention": { - "surveysTransferred": 5, - "reportsArchived": 2, - "transferredTo": null - } - } -} -``` - -::: warning Data Deletion User deletion is permanent and cannot be undone. -Consider deactivating users instead of deleting them to preserve historical data -and analytics. ::: - -## Bulk Operations - -### Bulk Create Users - -Create multiple users in a single request. - -```http -POST /api/v1/users/bulk -``` - -```json -{ - "users": [ - { - "email": "user1@company.com", - "firstName": "User", - "lastName": "One", - "role": "employee", - "department": "Engineering" - }, - { - "email": "user2@company.com", - "firstName": "User", - "lastName": "Two", - "role": "employee", - "department": "Design" - } - ], - "sendInvitations": true -} -``` - -### Bulk Update Users - -Update multiple users at once. - -```http -PATCH /api/v1/users/bulk -``` - -```json -{ - "userIds": ["user_123", "user_456", "user_789"], - "updates": { - "department": "New Department", - "metadata": { - "migrated": true - } - } -} -``` - -## User Invitations - -### Send Invitation - -Send an invitation to an existing user or create a new user with invitation. - -```http -POST /api/v1/users/{userId}/invite -``` - -```json -{ - "message": "Welcome to our WorkSight organization!", - "expiresIn": "7d" -} -``` - -### Resend Invitation - -Resend an invitation to a user with pending status. - -```http -POST /api/v1/users/{userId}/invite/resend -``` - -### Cancel Invitation - -Cancel a pending invitation. - -```http -DELETE /api/v1/users/{userId}/invite +curl http://localhost:3123/users ``` -## User Search - -### Advanced Search - -Search users with complex filters. +## Get one employee ```http -POST /api/v1/users/search -``` - -```json -{ - "query": "engineering", - "filters": { - "roles": ["employee", "manager"], - "departments": ["Engineering", "Product"], - "status": ["active"], - "startDateRange": { - "from": "2023-01-01", - "to": "2023-12-31" - } - }, - "sort": { - "field": "lastLoginAt", - "order": "desc" - }, - "page": 1, - "limit": 20 -} +GET /users/:id ``` -## User Statistics +Returns a single `EmployeeProfile`, or **404** when the id is not in fixtures. -### Get User Statistics - -Retrieve usage and engagement statistics for a user. +## Employee stats ```http -GET /api/v1/users/{userId}/stats -``` - -```json -{ - "success": true, - "data": { - "engagement": { - "surveysCompleted": 15, - "averageCompletionTime": 180, - "lastSurveyAt": "2024-01-20T10:30:00Z", - "streakDays": 7 - }, - "wellbeing": { - "currentScore": 7.2, - "averageScore": 6.8, - "trend": "improving", - "lastAssessmentAt": "2024-01-22T14:00:00Z" - }, - "activity": { - "loginCount": 45, - "lastLoginAt": "2024-01-22T09:15:00Z", - "sessionDuration": 1200, - "pageViews": 156 - } - } -} +GET /users/stats ``` -## User Groups +Aggregate counts (totals, roles, departments) derived from the same fixture set. -### Get User Groups - -Retrieve groups that a user belongs to. +## Teams ```http -GET /api/v1/users/{userId}/groups +GET /teams +GET /teams/:id ``` -### Add User to Group - -Add a user to a specific group. - -```http -POST /api/v1/users/{userId}/groups/{groupId} -``` +Returns `Team[]` / one `Team` from `@worksight/common`. -### Remove User from Group +## Shape source of truth -Remove a user from a group. +Prefer TypeScript types from `@worksight/common/types` over copy-pasted +interfaces in docs. The Nest controllers/services map lookup helpers from +`@worksight/common/utils` onto those types. -```http -DELETE /api/v1/users/{userId}/groups/{groupId} -``` - -## Error Handling - -### Common Errors - -#### User Not Found - -```json -{ - "success": false, - "error": { - "code": "USER_NOT_FOUND", - "message": "User with ID 'user_999' not found" - } -} -``` - -#### Email Already Exists - -```json -{ - "success": false, - "error": { - "code": "EMAIL_ALREADY_EXISTS", - "message": "A user with email 'john@company.com' already exists", - "details": { - "existingUserId": "user_123" - } - } -} -``` - -#### Invalid Role - -```json -{ - "success": false, - "error": { - "code": "INVALID_ROLE", - "message": "Role 'super_admin' is not valid for this organization", - "details": { - "validRoles": ["admin", "manager", "employee", "contractor", "viewer"] - } - } -} -``` +## Not implemented -#### Insufficient Permissions +- Create / update / delete users +- Invitations, suspension, password reset via this API +- Pagination query params (`page`, `limit`) on `/users` +- API-key `Authorization` headers +- Persistence in Supabase -```json -{ - "success": false, - "error": { - "code": "INSUFFICIENT_PERMISSIONS", - "message": "Cannot modify user with higher privileges", - "details": { - "requiredRole": "admin", - "currentRole": "manager" - } - } -} -``` - -## Best Practices - -### User Management - -1. **Email Validation**: Always validate email addresses before creating users -2. **Role Assignment**: Use the principle of least privilege when assigning - roles -3. **Bulk Operations**: Use bulk endpoints for large user imports/updates -4. **Data Transfer**: When deleting users, consider transferring their data to - another user -5. **Audit Trail**: Keep track of user changes for compliance and debugging - -### Performance Optimization - -```javascript -// Batch user operations when possible -const users = await Promise.all([ - worksight.users.get('user_1'), - worksight.users.get('user_2'), - worksight.users.get('user_3'), -]); - -// Better: Use bulk endpoint -const users = await worksight.users.getBulk(['user_1', 'user_2', 'user_3']); -``` - -### Security Considerations - -1. **Sensitive Data**: Never store sensitive information in user metadata -2. **Access Control**: Implement proper role-based access control -3. **Data Retention**: Follow data retention policies when deleting users -4. **Audit Logging**: Log all user management operations - -## SDK Examples - -### JavaScript/TypeScript - -```typescript -import { WorkSight } from 'apps/sdk'; - -const worksight = new WorkSight({ - apiKey: process.env.WORKSIGHT_API_KEY, -}); - -// Create a new user -const newUser = await worksight.users.create({ - email: 'john.doe@company.com', - firstName: 'John', - lastName: 'Doe', - role: 'employee', - department: 'Engineering', - sendInvitation: true, -}); - -// Update user preferences -await worksight.users.update('user_123', { - preferences: { - theme: 'dark', - emailNotifications: false, - }, -}); - -// Search users -const engineers = await worksight.users.search({ - query: 'engineering', - filters: { - departments: ['Engineering'], - roles: ['employee', 'manager'], - }, -}); -``` - -### Python - -```python -from worksight import WorkSight - -worksight = WorkSight(api_key=os.environ['WORKSIGHT_API_KEY']) - -# Create a new user -new_user = worksight.users.create( - email='john.doe@company.com', - first_name='John', - last_name='Doe', - role='employee', - department='Engineering', - send_invitation=True -) - -# Update user status -worksight.users.update_status( - user_id='user_123', - status='inactive', - reason='Employee left the company' -) -``` +For tasks tied to employees, see [API overview](./overview.md) (`/tasks`, +`/activities`). diff --git a/apps/docs/website/dev/nextjs.md b/apps/docs/website/dev/nextjs.md index a5d4e80..7933b85 100644 --- a/apps/docs/website/dev/nextjs.md +++ b/apps/docs/website/dev/nextjs.md @@ -1,39 +1,43 @@ -# Next.js Guide +# Next.js (web app) -## What is Next.js? +The web package is **`@worksight/web`** under `apps/web`, using the **App +Router** on **Next.js 15** (React 19). -Next.js is a React framework for building full-stack web apps with server-side -rendering, API routes, and more. +## Layout -## How to Use +```text +apps/web/src/ +β”œβ”€β”€ app/ # App Router routes +β”œβ”€β”€ components/ # UI +β”œβ”€β”€ lib/ # helpers (incl. MVP common bridges when wired) +β”œβ”€β”€ auth/ # auth helpers +└── __tests__/ # Jest tests (excluded from app type-check) +``` -1. **Pages and Routing** - - Files in `pages/` become routes automatically. - - Example: `pages/about.tsx` β†’ `/about` +## Data for MVP -2. **API Routes** - - Place serverless functions in `pages/api/`. - - Example: +Dashboard / admin / tasks views should consume `@worksight/common` fixtures via +a thin bridge (e.g. `src/lib/mvp-data.ts` on the wire-web workstream). That is +**not** the same as calling Nest or Supabase for those lists yet. - ```typescript - // pages/api/hello.ts - export default function handler(req, res) { - res.status(200).json({ message: 'Hello World' }); - } - ``` +## Dev / build -3. **Data Fetching** - - Use `getServerSideProps`, `getStaticProps`, or React Server Components for - data fetching. +```bash +pnpm --filter @worksight/common build +pnpm --filter @worksight/web dev +pnpm --filter @worksight/web build +pnpm --filter @worksight/web type-check +``` -4. **Styling** - - Use Tailwind CSS, CSS Modules, or any CSS-in-JS solution. +Or from the repo root: `pnpm dev:web` / `pnpm build:web`. -5. **Deployment** - - Deploy easily to Vercel or any Node.js host. +## Deploy -## Tips +Vercel project **`worksight`**, Root Directory **`apps/web`**, config +`apps/web/vercel.json`. See [Deployment](/guide/deployment). -- Use the App Router (`app/`) for new features (Next.js 13+). -- Leverage API routes for backend logic. -- Use environment variables for secrets. +## Notes + +- Prefer App Router (`app/`), not the legacy `pages/` router. +- Backend HTTP for the monorepo lives in Nest (`apps/api`), not Next `pages/api` + route handlers as the primary API. diff --git a/apps/docs/website/dev/overview.md b/apps/docs/website/dev/overview.md index e69de29..9462241 100644 --- a/apps/docs/website/dev/overview.md +++ b/apps/docs/website/dev/overview.md @@ -0,0 +1,38 @@ +# Developer overview + +Contributor-oriented notes for the WorkSight monorepo. + +## Packages + +| Package | Path | Role | +| ------------------- | ----------------- | ------------------------ | +| `@worksight/web` | `apps/web` | Next.js 15 UI | +| `@worksight/api` | `apps/api` | NestJS API | +| `@worksight/docs` | `apps/docs` | VitePress | +| `@worksight/common` | `packages/common` | Types, fixtures, lookups | +| `@worksight/assets` | `packages/assets` | Shared assets | + +## Commands + +```bash +pnpm install +pnpm --filter @worksight/common build +pnpm type-check +pnpm lint +pnpm --filter @worksight/web dev +PORT=3123 pnpm --filter @worksight/api dev +pnpm --filter @worksight/docs build +``` + +## Docs map + +- Stack notes: [Next.js](./nextjs.md), [VitePress](./vitepress.md), + [Jest](./jest.md), [Supabase](./supabase.md) +- API: [Overview](./api/overview.md), [Users](./api/user-management.md), + [Auth status](./api/authentication.md) +- Product/feature drafts under `/features/*` may still describe aspirational UX + β€” prefer guide + API pages for MVP truth. + +## Handoffs + +Repo: `docs/mvp/README.md` and `docs/handoffs/` (GitHub issues #14–#20). diff --git a/apps/docs/website/dev/supabase.md b/apps/docs/website/dev/supabase.md index 867b73d..4eabde4 100644 --- a/apps/docs/website/dev/supabase.md +++ b/apps/docs/website/dev/supabase.md @@ -1,154 +1,36 @@ -# Supabase Comprehensive Guide +# Supabase (web, optional) -## What is Supabase? +Supabase is **optional** for `@worksight/web` auth / online mode. MVP dashboard +and Nest list data come from **`@worksight/common` fixtures**, not from Supabase +tables. -Supabase is an open-source Firebase alternative providing a hosted Postgres -database, authentication, real-time APIs, and storage. It integrates easily with -modern web frameworks like Next.js. +## When you need it ---- +- `NEXT_PUBLIC_IS_OFFLINE=false` (and matching `IS_OFFLINE`) +- A Supabase project URL + publishable (anon) key -## 1. Setup +For fixture / offline demos, leave offline mode on and skip Supabase entirely +(`apps/web/env.example`). -### a. Create a Supabase Project +## Env vars (this repo) -1. Go to [supabase.com](https://supabase.com/) and sign up. -2. Create a new project. -3. Note your project URL and anon/public API key (found in Project Settings > - API). - -### b. Install Supabase Client - -```sh -npm install @supabase/supabase-js -``` - -### c. Configure Environment Variables - -Add these to your `.env.local`: - -``` +```bash +# apps/web/.env.local NEXT_PUBLIC_SUPABASE_URL=your-project-url -NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key -``` - ---- - -## 2. Initialize Supabase Client - -Create a utility file (e.g., `lib/supabase.ts`): - -```typescript -import { createClient } from '@supabase/supabase-js'; - -const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; -const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!; -export const supabase = createClient(supabaseUrl, supabaseKey); +NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-anon-key +NEXT_PUBLIC_IS_OFFLINE=false +IS_OFFLINE=false ``` ---- - -## 3. Usage Patterns - -### a. CRUD Operations - -```typescript -// Fetch all tasks -const { data, error } = await supabase.from('tasks').select('*'); - -// Insert a new task -const { data, error } = await supabase - .from('tasks') - .insert([{ title: 'New Task' }]); - -// Update a task -const { data, error } = await supabase - .from('tasks') - .update({ done: true }) - .eq('id', 1); - -// Delete a task -const { data, error } = await supabase.from('tasks').delete().eq('id', 1); -``` - -### b. Authentication - -```typescript -// Sign up -const { data, error } = await supabase.auth.signUp({ - email: 'user@example.com', - password: 'password', -}); - -// Sign in -const { data, error } = await supabase.auth.signInWithPassword({ - email: 'user@example.com', - password: 'password', -}); - -// Sign out -const { error } = await supabase.auth.signOut(); -``` - -### c. Real-time Subscriptions - -```typescript -supabase - .channel('public:tasks') - .on( - 'postgres_changes', - { event: '*', schema: 'public', table: 'tasks' }, - (payload) => { - console.log('Change received!', payload); - } - ) - .subscribe(); -``` - ---- - -## 4. Security & Best Practices - -- **Never expose your service role key** to the frontend. -- Use **Row Level Security (RLS)** in Supabase for fine-grained access control. -- Store sensitive keys in environment variables, not in code. -- Use Supabase Auth for user authentication and session management. -- Validate all user input before writing to the database. - ---- - -## 5. Advanced Usage - -- **Storage:** Upload and manage files with Supabase Storage. -- **Edge Functions:** Write serverless functions for custom backend logic. -- **Policies:** Write RLS policies in the Supabase dashboard for secure data - access. -- **Server-side Usage:** Use the service key only in API routes or server - functions. - ---- - -## 6. Troubleshooting - -- **Auth errors:** Double-check your API keys and project URL. -- **RLS issues:** Ensure your policies allow the intended operations for - authenticated users. -- **Network issues:** Make sure your environment variables are set and - accessible. - ---- - -## 7. Resources +Client helpers live under `apps/web` (e.g. `src/lib/supabase.ts`, +`src/utils/supabase/*`). Prefer those over inventing a new root client. -- [Supabase Docs](https://supabase.com/docs) -- [Supabase GitHub](https://github.com/supabase/supabase) -- [Next.js Integration Guide](https://supabase.com/docs/guides/getting-started/quickstarts/nextjs) +## Not true for MVP Nest routes ---- +- Nest `/users`, `/teams`, `/tasks`, `/activities` do **not** read Supabase. +- Do not document service-role keys or table schemas as required for the MVP API + slice. -## Tips +## Further reading -- Store keys in environment variables. -- Use Supabase Auth for secure authentication. -- Use TypeScript for type safety with Supabase responses. -- Regularly review your RLS policies for security. +Official docs: diff --git a/apps/docs/website/guide/configuration.md b/apps/docs/website/guide/configuration.md index 6e56080..b29ef67 100644 --- a/apps/docs/website/guide/configuration.md +++ b/apps/docs/website/guide/configuration.md @@ -1,355 +1,70 @@ # Configuration -Learn how to configure WorkSight for your organization's specific needs. +Configure WorkSight with the env vars and packages that actually exist in the +repo. -## Environment Configuration +## Web (`apps/web`) -### Core Settings +Copy the template: -WorkSight uses environment variables for configuration. Here are the essential -settings: - -#### Database Configuration - -```env -# Primary database connection -DATABASE_URL="postgresql://username:password@localhost:5432/worksight" - -# Database connection pool settings -DATABASE_MAX_CONNECTIONS=20 -DATABASE_IDLE_TIMEOUT=30000 -``` - -#### Authentication Settings - -```env -# NextAuth configuration -NEXTAUTH_URL="https://your-domain.com" -NEXTAUTH_SECRET="your-256-bit-secret" - -# Session settings -SESSION_MAX_AGE=2592000 # 30 days -SESSION_UPDATE_AGE=86400 # 24 hours -``` - -#### Supabase Configuration - -```env -# Supabase project settings -NEXT_PUBLIC_SUPABASE_URL="https://your-project.supabase.co" -NEXT_PUBLIC_SUPABASE_ANON_KEY="your-anon-key" -SUPABASE_SERVICE_ROLE_KEY="your-service-role-key" -``` - -### Email Configuration - -```env -# Email provider settings -EMAIL_FROM="noreply@yourcompany.com" -EMAIL_SERVER_HOST="smtp.yourprovider.com" -EMAIL_SERVER_PORT=587 -EMAIL_SERVER_USER="your-smtp-username" -EMAIL_SERVER_PASSWORD="your-smtp-password" -``` - -### Optional Integrations - -```env -# Analytics -NEXT_PUBLIC_GOOGLE_ANALYTICS_ID="GA_MEASUREMENT_ID" - -# Error tracking -SENTRY_DSN="your-sentry-dsn" - -# File storage -AWS_ACCESS_KEY_ID="your-aws-key" -AWS_SECRET_ACCESS_KEY="your-aws-secret" -AWS_REGION="us-east-1" -AWS_BUCKET_NAME="your-bucket" -``` - -## Application Configuration - -### Site Configuration - -Edit `src/config/site.ts` to customize your instance: - -```typescript -export const siteConfig = { - name: 'WorkSight', - description: 'Employee well-being and task management platform', - url: 'https://your-domain.com', - ogImage: 'https://your-domain.com/og.png', - - // Company information - company: { - name: 'Your Company Name', - email: 'contact@yourcompany.com', - phone: '+1 (555) 123-4567', - }, - - // Feature flags - features: { - enableSurveys: true, - enableReporting: true, - enableTeamManagement: true, - enableNotifications: true, - }, -}; -``` - -### Survey Configuration - -Configure survey settings in `src/config/surveys.ts`: - -```typescript -export const surveyConfig = { - // Default survey intervals - burnoutAssessment: { - frequency: 'weekly', // daily, weekly, monthly - reminderTime: '09:00', - timezone: 'America/New_York', - }, - - // Survey customization - questions: { - useCustomQuestions: false, - customQuestionsPath: '/surveys/custom.json', - }, - - // Scoring configuration - scoring: { - burnoutThreshold: 70, - warningThreshold: 50, - scale: '1-5', // 1-5, 1-7, 1-10 - }, -}; -``` - -## User Roles and Permissions - -### Role Configuration - -Define user roles and permissions: - -```typescript -// src/config/roles.ts -export const roles = { - admin: { - permissions: [ - 'user.create', - 'user.update', - 'user.delete', - 'survey.create', - 'survey.update', - 'survey.delete', - 'report.view', - 'report.export', - ], - }, - manager: { - permissions: ['team.view', 'team.manage', 'survey.view', 'report.view'], - }, - employee: { - permissions: [ - 'task.create', - 'task.update', - 'survey.take', - 'profile.update', - ], - }, -}; -``` - -## Database Configuration - -### Connection Settings - -For production deployments, configure database connection pooling: - -```typescript -// src/lib/database.ts -export const dbConfig = { - host: process.env.DB_HOST, - port: parseInt(process.env.DB_PORT || '5432'), - database: process.env.DB_NAME, - username: process.env.DB_USER, - password: process.env.DB_PASSWORD, - - // Connection pool - pool: { - min: 2, - max: 20, - acquire: 30000, - idle: 10000, - }, - - // SSL configuration for production - ssl: - process.env.NODE_ENV === 'production' - ? { - require: true, - rejectUnauthorized: false, - } - : false, -}; -``` - -## Security Configuration - -### Authentication Providers - -Configure supported authentication methods: - -```typescript -// src/config/auth.ts -export const authProviders = { - email: { - enabled: true, - requireVerification: true, - }, - google: { - enabled: true, - clientId: process.env.GOOGLE_CLIENT_ID, - clientSecret: process.env.GOOGLE_CLIENT_SECRET, - }, - microsoft: { - enabled: false, - tenantId: process.env.MICROSOFT_TENANT_ID, - clientId: process.env.MICROSOFT_CLIENT_ID, - clientSecret: process.env.MICROSOFT_CLIENT_SECRET, - }, - saml: { - enabled: false, - entityId: process.env.SAML_ENTITY_ID, - ssoUrl: process.env.SAML_SSO_URL, - certificate: process.env.SAML_CERTIFICATE, - }, -}; -``` - -### Password Policy - -```typescript -export const passwordPolicy = { - minLength: 8, - requireUppercase: true, - requireLowercase: true, - requireNumbers: true, - requireSpecialChars: true, - maxAge: 90, // days - historyCount: 5, -}; +```bash +cp apps/web/env.example apps/web/.env.local ``` -## Deployment Configuration - -### Production Settings +### Supported variables -```env -# Environment -NODE_ENV=production +From `apps/web/env.example`: -# Security -SECURE_COOKIES=true -CSRF_SECRET="your-csrf-secret" - -# Performance -ENABLE_COMPRESSION=true -CACHE_TTL=3600 +```bash +# Force offline mode (disables signup / online-only features) +NEXT_PUBLIC_IS_OFFLINE=false +IS_OFFLINE=false -# Monitoring -LOG_LEVEL=info -ENABLE_METRICS=true +# Optional when offline mode is enabled +# NEXT_PUBLIC_SUPABASE_URL=your_supabase_url_here +# NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your_supabase_anon_key_here ``` -### Health Checks +Additional app branding vars may be set in Vercel for production (see +[Deployment](./deployment.md)): -Configure health check endpoints: - -```typescript -// src/config/health.ts -export const healthConfig = { - endpoints: { - '/health': { - checks: ['database', 'redis', 'external-apis'], - }, - '/health/liveness': { - checks: ['basic'], - }, - '/health/readiness': { - checks: ['database', 'migrations'], - }, - }, -}; +```bash +NEXT_PUBLIC_APP_NAME=WorkSight +NEXT_PUBLIC_APP_DESCRIPTION=Employee Well-being Analytics Platform +NEXT_PUBLIC_APP_URL=https://your-domain.vercel.app ``` -## Advanced Configuration +There is **no** NextAuth config, root `DATABASE_URL`, `pnpm db:migrate`, or +`pnpm config:validate` script in this monorepo. -### Custom Themes +## API (`apps/api`) -Customize the application theme: +Nest boots with `app.listen(process.env.PORT ?? 3000)`. Set `PORT` when web +already occupies 3000: -```typescript -// src/config/theme.ts -export const themeConfig = { - primaryColor: '#3b82f6', - secondaryColor: '#64748b', - accentColor: '#f59e0b', - - // Dark mode - darkMode: { - enabled: true, - default: false, - }, - - // Custom CSS - customStyles: '/styles/custom.css', -}; +```bash +PORT=3123 pnpm --filter @worksight/api dev ``` -### Notification Configuration - -```typescript -// src/config/notifications.ts -export const notificationConfig = { - email: { - enabled: true, - templates: { - welcome: 'welcome-template', - surveyReminder: 'survey-reminder-template', - reportReady: 'report-ready-template', - }, - }, +MVP endpoints read **`@worksight/common` fixtures** in-process. No Supabase +service-role key is required for those routes today. - push: { - enabled: false, - vapidPublicKey: process.env.VAPID_PUBLIC_KEY, - vapidPrivateKey: process.env.VAPID_PRIVATE_KEY, - }, +## Docs (`apps/docs`) - inApp: { - enabled: true, - maxNotifications: 100, - retentionDays: 30, - }, -}; -``` +VitePress uses `VITE_HOSTNAME` / `VITE_BASE` when set (see +`apps/docs/.vitepress/config.mts`). Defaults work for local `pnpm dev:docs`. -## Validation +## Shared package -After configuration, validate your setup: +Consumers resolve `@worksight/common` from the workspace. Build it before +type-checking or running API/web against dist: ```bash -# Check configuration -pnpm config:validate - -# Test database connection -pnpm db:test +pnpm --filter @worksight/common build +``` -# Verify email settings -pnpm email:test +## Vercel -# Run health checks -pnpm health:check -``` +Env vars are **dashboard-managed per project**. Do not commit secrets into +`vercel.json`. Three projects: `worksight`, `worksight-api`, `worksight-docs` +with Root Directories `apps/web`, `apps/api`, `apps/docs`. diff --git a/apps/docs/website/guide/deployment.md b/apps/docs/website/guide/deployment.md new file mode 100644 index 0000000..f335e5a --- /dev/null +++ b/apps/docs/website/guide/deployment.md @@ -0,0 +1,50 @@ +# Deployment + +WorkSight is a pnpm + Turborepo monorepo. Deploy **each app** with its own +target β€” there is no single root Vercel project that builds everything. + +## Vercel projects + +| App | Package | Vercel project | Root Directory | +| ----------- | ----------------- | ---------------- | -------------- | +| `apps/web` | `@worksight/web` | `worksight` | `apps/web` | +| `apps/api` | `@worksight/api` | `worksight-api` | `apps/api` | +| `apps/docs` | `@worksight/docs` | `worksight-docs` | `apps/docs` | + +Each project loads **only** the `vercel.json` under its Root Directory. Vercel +does not merge a repo-root `vercel.json` with nested ones. + +Shared settings in practice: + +- Production branch: **`canary`** +- Install: `pnpm install --frozen-lockfile` +- Build: `pnpm --filter @worksight/ build` +- Include source files outside Root Directory: **on** +- Skip unaffected projects: **on** + +## API caveat + +`apps/api` still boots with `app.listen()`. A Vercel deployment builds `dist/` +but does **not** expose a serverless function yet. Use Docker for a working API: + +```bash +docker compose up -d --build +``` + +## Local verify before ship + +```bash +pnpm --filter @worksight/common build +pnpm type-check +pnpm --filter @worksight/web build +pnpm --filter @worksight/docs build +pnpm --filter @worksight/api build +``` + +## Canonical guide + +The long-form checklist and dashboard steps live in the repo at +[`doc/DEPLOYMENT.md`](https://github.com/4sightorg/worksight/blob/feat/mvp-stabilize/doc/DEPLOYMENT.md). + +There is **no** root `deploy.yml` / `pnpm deploy` script. Production deploys are +driven by each Vercel project's Git integration. diff --git a/apps/docs/website/guide/getting-started.md b/apps/docs/website/guide/getting-started.md index 63a60b8..04ccbba 100644 --- a/apps/docs/website/guide/getting-started.md +++ b/apps/docs/website/guide/getting-started.md @@ -1,103 +1,99 @@ # Getting Started -Welcome to WorkSight! This guide will help you get up and running quickly. +Welcome to WorkSight. This guide gets the monorepo running locally for the MVP +slice. ## What is WorkSight? -WorkSight is a comprehensive wellness and task management platform designed to -help organizations monitor employee well-being while managing productivity -effectively. +WorkSight is an employee well-being and task analytics platform. The monorepo +includes: -## Quick Start +- **`@worksight/web`** β€” Next.js 15 app (dashboards, surveys UI, admin) +- **`@worksight/api`** β€” NestJS API +- **`@worksight/docs`** β€” this VitePress site +- **`@worksight/common`** β€” shared types, fixtures, and lookup utilities -### Prerequisites +For the MVP, **populated dashboard / API data comes from `@worksight/common` +fixtures**, not from a live database. Supabase is optional for web auth / online +mode. -- Node.js 18+ and pnpm -- Supabase account (for online features) -- Modern web browser +## Prerequisites -### Installation +- Node.js 18+ (20+ recommended) +- pnpm 9+ (repo pins pnpm 10 via `packageManager`) +- Git +- Optional: Supabase project (only if you leave offline mode off) -1. Clone the repository: +## Install ```bash git clone https://github.com/4sightorg/worksight.git cd worksight +pnpm install ``` -2. Install dependencies: +## Environment (web) ```bash -pnpm install +cp apps/web/env.example apps/web/.env.local ``` -3. Set up environment variables: +Minimal offline-friendly settings: ```bash -cp apps/web/.env.example apps/web/.env.local +NEXT_PUBLIC_IS_OFFLINE=true +IS_OFFLINE=true ``` -4. Configure your Supabase credentials in `.env.local`: +For online Supabase auth, set (names match `env.example`): -```env +```bash NEXT_PUBLIC_SUPABASE_URL=your_supabase_url -NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key +NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your_supabase_anon_key +NEXT_PUBLIC_IS_OFFLINE=false ``` -5. Start the development server: +## Run locally + +Build shared packages when you need API/web against compiled common: ```bash -pnpm run dev +pnpm --filter @worksight/common build ``` -### First Login - -WorkSight supports both online and offline modes. For testing, you can use these -credentials: - -**Executives:** - -- Email: `test@worksight.app` -- Password: `testuser` - -**Employees:** - -- Email: `jane.doe@worksight.com` -- Password: `testuser` - -**Admin:** - -- Email: `admin@worksight.com` -- Password: `testuser` - -## Core Features +```bash +# Web β†’ http://localhost:3000 +pnpm dev:web -### 🏠 Dashboard +# Docs β†’ http://localhost:5173 (VitePress default) +pnpm dev:docs -Role-based dashboards showing: +# API (defaults to PORT 3000 β€” pick another if web is running) +PORT=3123 pnpm --filter @worksight/api dev +``` -- Burnout level tracking -- Task summaries -- Team analytics (for managers/executives) -- Quick actions +Or `pnpm dev` to start all Turbo `dev` tasks. -### πŸ“‹ Task Management +## MVP data you should see -- Kanban board with drag-and-drop -- Table view with inline editing -- Priority and status management -- Story point estimation +Once web is wired to common fixtures, dashboards/admin/tasks views use employee, +team, assignment, and activity fixtures from `@worksight/common`. The Nest API +exposes the same shapes on: -### 🧘 Wellness Tracking +- `GET /users`, `/users/:id`, `/users/stats` +- `GET /teams`, `/teams/:id` +- `GET /tasks` (`?employee_id=`), `/tasks/:id`, `/tasks/stats/:employeeId` +- `GET /activities` +- `GET /`, `/ping`, `/health` -- Burnout assessment surveys -- Progress tracking over time -- Personalized recommendations -- Risk level monitoring +There is **no** Supabase-backed persistence for those API routes yet, and the +API has **no** Vercel serverless handler (`app.listen` only) β€” use Docker for a +deployed API. See [Deployment](/guide/deployment). -### βš™οΈ Settings +## Next steps -- User preferences -- Notification settings -- Theme customization -- Admin controls +- [Installation](./installation.md) β€” environments and Docker notes +- [Configuration](./configuration.md) β€” real env vars only +- [API overview](/dev/api/overview) β€” Nest fixture endpoints +- [MVP plan](https://github.com/4sightorg/worksight/blob/feat/mvp-stabilize/docs/mvp/README.md) + (epic #14) diff --git a/apps/docs/website/guide/installation.md b/apps/docs/website/guide/installation.md index c70a053..7c7494e 100644 --- a/apps/docs/website/guide/installation.md +++ b/apps/docs/website/guide/installation.md @@ -1,198 +1,122 @@ # Installation -This guide provides detailed instructions for installing and setting up -WorkSight in different environments. +Install and run the WorkSight monorepo (pnpm + Turbo). -## Development Environment +## Prerequisites -### Prerequisites +- **Node.js** 18+ (20+ recommended) +- **pnpm** 9+ (lockfile expects pnpm 10 β€” see root `packageManager`) +- **Git** +- Optional: **Docker** / Docker Compose for the Nest API -Ensure you have the following installed on your system: +## Native (recommended for development) -- **Node.js**: Version 20.0.0 or higher -- **pnpm**: Version 8.0.0 or higher (recommended package manager) -- **Git**: For version control - -### System Requirements - -- **Operating System**: Windows 10+, macOS 10.15+, or Linux -- **Memory**: 502MB RAM minimum (1GB recommended) -- **Storage**: 256MB free disk space - -### Step-by-Step Installation - -#### Docker Installation - -```bash -docker run -rm -it ghcr.io:4sight/worksight/web:latest -``` - -#### Docker Compose Installation - -```bash -docker compose up -d -``` - -#### Native Installation - -1. **Clone the Repository** +1. **Clone** ```bash git clone https://github.com/4sightorg/worksight.git cd worksight ``` -2. **Install Dependencies** +2. **Install** ```bash - # Install pnpm if you haven't already - npm install -g pnpm - - # Install project dependencies + corepack enable pnpm install ``` -3. **Environment Configuration** - - ```bash - # Copy environment template - cp .env.example .env.local - ``` - -4. **Configure Environment Variables** - - Edit `.env.local` with your configuration: - - ```env - # Database - DATABASE_URL="your-database-url" - - # Authentication - NEXTAUTH_URL="http://localhost:3000" - NEXTAUTH_SECRET="your-secret-key" - - # Supabase - NEXT_PUBLIC_SUPABASE_URL="your-supabase-url" - NEXT_PUBLIC_SUPABASE_ANON_KEY="your-supabase-anon-key" - ``` - -5. **Database Setup** +3. **Web env** ```bash - # Run database migrations - pnpm db:migrate - - # Seed initial data (optional) - pnpm db:seed + cp apps/web/env.example apps/web/.env.local ``` -6. **Start Development Server** + Edit `apps/web/.env.local`. For fixture / offline MVP work: ```bash - pnpm dev + NEXT_PUBLIC_IS_OFFLINE=true + IS_OFFLINE=true ``` - The application will be available at `http://localhost:3000` - -## Production Deployment + There is no root `.env.example`, no `pnpm db:migrate` / `pnpm db:seed`, and + no NextAuth-required setup for the MVP slice. -### Using Vercel (Recommended) - -1. **Deploy to Vercel** +4. **Build shared package** ```bash - # Install Vercel CLI - npm install -g vercel - - # Deploy - vercel + pnpm --filter @worksight/common build ``` -2. **Configure Environment Variables** - - Set the following in your Vercel dashboard: - - `DATABASE_URL` - - `NEXTAUTH_URL` - - `NEXTAUTH_SECRET` - - `NEXT_PUBLIC_SUPABASE_URL` - - `NEXT_PUBLIC_SUPABASE_ANON_KEY` - -### Using Docker - -1. **Build Docker Image** +5. **Start apps** ```bash - docker build -t worksight . + pnpm dev:web # :3000 + pnpm dev:docs # VitePress + PORT=3123 pnpm --filter @worksight/api dev # Nest ``` -2. **Run Container** - - ```bash - docker run -p 3000:3000 --env-file .env.local worksight - ``` +## Docker Compose -### Manual Deployment +From the repo root (API-oriented path; see `docker-compose.yml`): -1. **Build for Production** +```bash +docker compose up -d --build +``` - ```bash - pnpm build - ``` +Prefer this for a **running Nest API**. The Vercel API project builds `dist/` +but does not yet expose a serverless handler. -2. **Start Production Server** +## Production builds (local) - ```bash - pnpm start - ``` +```bash +pnpm --filter @worksight/common build +pnpm --filter @worksight/web build +pnpm --filter @worksight/api build +pnpm --filter @worksight/docs build +``` -## Database Setup +Or `pnpm build` via Turbo. -### Supabase (Recommended) +## Vercel (hosted) -1. Create a new project at [supabase.com](https://supabase.com) -2. Copy your project URL and anon key -3. Run the database migrations provided in `/supabase/migrations` +WorkSight uses **three** Vercel projects with per-app Root Directories β€” not a +single root `vercel.json`: -### Self-hosted PostgreSQL +| Project | Root Directory | +| ---------------- | -------------- | +| `worksight` | `apps/web` | +| `worksight-api` | `apps/api` | +| `worksight-docs` | `apps/docs` | -1. Install PostgreSQL 14+ -2. Create a new database -3. Run the SQL schema from `/database/schema.sql` +Details: [Deployment](./deployment.md) and repo +[`doc/DEPLOYMENT.md`](https://github.com/4sightorg/worksight/blob/feat/mvp-stabilize/doc/DEPLOYMENT.md). ## Troubleshooting -### Common Issues - -**Port 3000 already in use** +**Port 3000 in use** ```bash -# Kill process using port 3000 -lsof -ti:3000 | xargs kill -9 - -# Or use a different port -PORT=3001 pnpm dev +PORT=3001 pnpm --filter @worksight/web dev +# or free the port, then retry ``` -**Database connection errors** +**Empty / stale `@worksight/common`** -- Verify your `DATABASE_URL` is correct -- Check if your database server is running -- Ensure network connectivity to your database +```bash +pnpm --filter @worksight/common build +``` -**Build errors** +**Reinstall** ```bash -# Clear cache and reinstall +pnpm clean rm -rf node_modules -rm pnpm-lock.yaml pnpm install ``` -### Getting Help +Do **not** delete `pnpm-lock.yaml` unless you intend to regenerate the lockfile. -If you encounter issues: +## Getting help -1. Check the [troubleshooting section] -2. Search existing - [GitHub issues](https://github.com/4sightorg/worksight/issues) -3. Create a new issue with detailed information +- [GitHub issues](https://github.com/4sightorg/worksight/issues) +- [MVP plan](https://github.com/4sightorg/worksight/blob/feat/mvp-stabilize/docs/mvp/README.md) diff --git a/apps/docs/website/guide/introduction.md b/apps/docs/website/guide/introduction.md index fddb015..398f36a 100644 --- a/apps/docs/website/guide/introduction.md +++ b/apps/docs/website/guide/introduction.md @@ -1,80 +1,47 @@ # Introduction -WorkSight is a comprehensive employee well-being and task management platform -designed to help organizations monitor and improve workplace productivity while -maintaining employee mental health. - -## What is WorkSight? - -WorkSight combines modern task management with advanced burnout assessment tools -to create a holistic approach to workplace wellness. Our platform helps both -employees and managers: - -- **Track Tasks Efficiently**: Organize and prioritize work with intuitive task - management -- **Monitor Well-being**: Regular burnout assessments and wellness check-ins -- **Generate Insights**: Comprehensive reporting on productivity and wellness - trends -- **Improve Culture**: Data-driven insights to build healthier work environments - -## Key Features - -### 🎯 Task Management - -- Create, assign, and track tasks -- Set priorities and deadlines -- Collaborate with team members -- Track time and progress - -### πŸ“Š Burnout Assessment - -- Regular wellness surveys -- Science-backed burnout indicators -- Personal wellness dashboards -- Early warning systems - -### πŸ‘₯ Team Management - -- Role-based access control -- Team productivity insights -- Manager dashboards -- Employee wellness monitoring - -### πŸ“ˆ Analytics & Reporting - -- Productivity metrics -- Wellness trends -- Custom reports -- Export capabilities - -## How It Works - -1. **Setup**: Configure your organization and invite team members -2. **Tasks**: Create and manage tasks using our intuitive interface -3. **Assess**: Regular wellness check-ins and burnout assessments -4. **Analyze**: Review insights and reports to improve workplace culture -5. **Improve**: Implement data-driven changes to enhance productivity and - wellness - -## Who Should Use WorkSight? - -- **HR Professionals**: Monitor employee wellness and engagement -- **Team Leaders**: Balance productivity with team well-being -- **Employees**: Track personal productivity and wellness -- **Organizations**: Build healthier, more productive work environments - -## Technology Stack - -WorkSight is built with modern technologies: - -- **Frontend**: Next.js 14, React, TypeScript -- **Backend**: Supabase, PostgreSQL -- **Authentication**: Supabase Auth -- **Deployment**: Vercel, GitHub Actions -- **Monitoring**: Built-in analytics and reporting - -## Getting Started - -Ready to transform your workplace? Check out our -[Getting Started Guide](./getting-started.md) to begin your journey with -WorkSight. +WorkSight helps organizations track employee well-being alongside work activity. +This documentation covers the **monorepo** as it exists today: Next.js web, +NestJS API, VitePress docs, and `@worksight/common`. + +## What ships in the repo + +| Package | Role | +| ------------------- | ---------------------------------------- | +| `@worksight/web` | Next.js 15 App Router UI | +| `@worksight/api` | NestJS HTTP API | +| `@worksight/docs` | VitePress site (`apps/docs`) | +| `@worksight/common` | Shared types, fixtures, lookup utilities | +| `@worksight/assets` | Shared assets | + +## MVP scope (honest) + +- Dashboards and Nest list/detail endpoints are driven by **`@worksight/common` + fixtures** for the MVP slice. +- **No** live Supabase persistence for those new API endpoints yet. +- Supabase Auth remains available on the web app when offline mode is off. +- External connectors (Jira, Trello, GitHub, Odoo, Slack) and production auth + hardening are **non-goals** for the current MVP epic. + +## Product surfaces (UI) + +- Role-aware dashboards and admin views +- Task / assignment views +- Survey and burnout-related UI (backed by common types/fixtures where wired) +- Offline-capable web mode for local demos + +## Technology stack + +- **Web:** Next.js 15, React 19, TypeScript, Tailwind CSS, shadcn/ui +- **API:** NestJS +- **Shared:** `@worksight/common` +- **Auth (web, optional):** Supabase Auth +- **Docs:** VitePress +- **Monorepo:** pnpm workspaces + Turbo +- **Hosting:** Vercel (three projects) + Docker for a working API + +## Getting started + +See [Getting Started](./getting-started.md) and +[Installation](./installation.md). Deployment layout: +[Deployment](./deployment.md). diff --git a/apps/docs/website/guide/overview.md b/apps/docs/website/guide/overview.md index 5b815f2..4c33393 100644 --- a/apps/docs/website/guide/overview.md +++ b/apps/docs/website/guide/overview.md @@ -1,166 +1,21 @@ -# API Overview +# Guide overview -WorkSight provides a comprehensive REST API for integrating with external -systems and building custom applications. +WorkSight documentation for operators and contributors. -## Base URL +## Start here -``` -Production: https://api.worksight.com -Development: http://localhost:3000/api -``` +1. [Introduction](./introduction.md) β€” what the monorepo is +2. [Getting started](./getting-started.md) β€” local run +3. [Installation](./installation.md) β€” native + Docker +4. [Configuration](./configuration.md) β€” real env vars +5. [Deployment](./deployment.md) β€” three Vercel projects + Docker API -## Authentication +## MVP reminders -WorkSight supports multiple authentication methods: +- Data for the current slice: **`@worksight/common` fixtures** +- Packages: `@worksight/web`, `@worksight/api`, `@worksight/docs`, + `@worksight/common` +- Stack: Next.js 15 + NestJS + pnpm/Turbo +- API on Vercel is not serverless yet β€” use Docker for a live API -### Bearer Token - -```bash -curl -H "Authorization: Bearer your_token_here" \ - https://api.worksight.com/users/me -``` - -### API Key - -```bash -curl -H "X-API-Key: your_api_key_here" \ - https://api.worksight.com/tasks -``` - -## Rate Limiting - -API requests are rate-limited based on your role: - -| Role | Requests/Hour | Burst Limit | -| -------- | ------------- | ----------- | -| Admin | 10,000 | 500 | -| Manager | 5,000 | 250 | -| Employee | 1,000 | 100 | -| Guest | 100 | 20 | - -## Response Format - -All API responses follow this structure: - -```json -{ - "success": true, - "data": {...}, - "message": "Operation completed successfully", - "timestamp": "2025-01-27T10:00:00Z" -} -``` - -### Error Format - -```json -{ - "success": false, - "error": { - "code": "VALIDATION_ERROR", - "message": "Invalid input data", - "details": {...} - }, - "timestamp": "2025-01-27T10:00:00Z" -} -``` - -## Core Endpoints - -### Users - -- `GET /api/users` - List users -- `GET /api/users/me` - Current user info -- `PUT /api/users/me` - Update profile - -### Tasks - -- `GET /api/tasks` - List tasks -- `POST /api/tasks` - Create task -- `PUT /api/tasks/:id` - Update task -- `DELETE /api/tasks/:id` - Delete task - -### Surveys - -- `POST /api/surveys/submit` - Submit survey -- `GET /api/surveys/results` - Get results -- `GET /api/surveys/history` - Survey history - -### Analytics - -- `GET /api/analytics/burnout` - Burnout statistics -- `GET /api/analytics/tasks` - Task analytics -- `GET /api/analytics/team` - Team metrics - -## SDKs - -### JavaScript/TypeScript - -```bash -npm install apps/api-client -``` - -```typescript -import { WorkSightAPI } from 'apps/api-client'; - -const api = new WorkSightAPI({ - baseURL: 'https://api.worksight.com', - apiKey: 'your_api_key' -}); - -// Get user tasks -const tasks = await api.tasks.list(); - -// Submit survey -const result = await api.surveys.submit({ - responses: {...}, - userId: 'user123' -}); -``` - -### Python - -```bash -pip install worksight-api -``` - -```python -from worksight import WorkSightAPI - -api = WorkSightAPI( - base_url='https://api.worksight.com', - api_key='your_api_key' -) - -# Get burnout analytics -analytics = api.analytics.burnout() -``` - -## Webhooks - -Subscribe to real-time events: - -### Available Events - -- `survey.completed` - Survey submission -- `task.created` - New task -- `task.updated` - Task status change -- `user.burnout_alert` - High burnout score - -### Configuration - -```json -{ - "url": "https://your-app.com/webhooks/worksight", - "events": ["survey.completed", "task.updated"], - "secret": "your_webhook_secret" -} -``` - -## OpenAPI Specification - -Full API documentation is available in OpenAPI format: - -- [View Interactive Docs](https://api.worksight.com/docs) -- [Download OpenAPI JSON](https://api.worksight.com/openapi.json) +Developer API notes live under [Dev β†’ API overview](/dev/api/overview). diff --git a/apps/docs/website/index.md b/apps/docs/website/index.md index 93b9c5a..befa8e0 100644 --- a/apps/docs/website/index.md +++ b/apps/docs/website/index.md @@ -47,8 +47,8 @@ features: UI. - icon: ⚑ - title: Real-time Sync + title: Shared data layer details: - Supabase integration with offline-first architecture for reliable - performance. + MVP dashboards and Nest routes use `@worksight/common` fixtures; optional + Supabase auth when online mode is enabled. --- diff --git a/doc/DEPLOYMENT.md b/doc/DEPLOYMENT.md index 0b422a1..7821973 100644 --- a/doc/DEPLOYMENT.md +++ b/doc/DEPLOYMENT.md @@ -1,252 +1,167 @@ -# πŸš€ WorkSight Deployment Guide +# WorkSight Deployment Guide -## Quick Deploy to Vercel +WorkSight is a **Turborepo + pnpm workspace** monorepo. There is no single +deploy artifact β€” each app ships on the platform that fits it: -### One-Click Deploy +| App | Package | Vercel project | Root Directory | Config source of truth | +| ----------- | ----------------- | ---------------- | -------------- | ----------------------- | +| `apps/web` | `@worksight/web` | `worksight` | `apps/web` | `apps/web/vercel.json` | +| `apps/api` | `@worksight/api` | `worksight-api` | `apps/api` | `apps/api/vercel.json` | +| `apps/docs` | `@worksight/docs` | `worksight-docs` | `apps/docs` | `apps/docs/vercel.json` | -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/4sightorg/worksight) +All three Vercel projects connect to the same GitHub repository +(`4sightorg/worksight`) with production branch **`canary`**, share +`pnpm install --frozen-lockfile`, and enable **Include source files outside of +the Root Directory** plus **skip unaffected projects**. The API can also run +under Docker (`docker-compose.yml` + `nginx/`). -### Manual Deployment +> **What repo config can and cannot do.** A `vercel.json` only configures +> build/routing behavior. It **cannot** create Vercel projects, set a project's +> **Root Directory**, add dashboard env vars, or link a Git repo. Those are +> dashboard/CLI actions (see below). -1. **Install Vercel CLI** +## How Vercel resolves config in this monorepo - ```bash - pnpm add -g vercel - ``` +Vercel reads **exactly one** `vercel.json` per project: the file at the +project's **Root Directory** (dashboard setting). It does **not** merge a root +`vercel.json` with a nested one. -2. **Login to Vercel** +- One Vercel project builds one output, so web, api, and docs need **separate** + projects. A single root `vercel.json` cannot govern all three. +- "Centralized" means **uniform, per-app configs** next to each app β€” not one + shared file. +- Each Root Directory points at its app; that app's `vercel.json` is what Vercel + loads. - ```bash - vercel login - ``` +Shared primitives: -3. **Deploy Preview** +- Install: `pnpm install --frozen-lockfile` +- Build: `pnpm --filter @worksight/ build` (Turbo `dependsOn: ["^build"]` + builds workspace deps such as `@worksight/common` first) +- Output: Next.js framework default for web; `.vitepress/dist` for docs; `dist` + for api - ```bash - pnpm run deploy:preview - ``` +Secrets live in the **dashboard**, not in `vercel.json`. -4. **Deploy Production** +## Vercel dashboard setup (one-time, per project) - ```bash - pnpm run deploy - ``` +### Web (`worksight` β†’ `apps/web`) -## Environment Variables +1. Import `4sightorg/worksight` as a Vercel project. +2. Set **Root Directory** to `apps/web`. +3. Keep **Include source files outside of the Root Directory** enabled. +4. Prefer install/build from `apps/web/vercel.json`; avoid dashboard overrides. +5. Add env vars per environment (see below). -### Required for Production +### Docs (`worksight-docs` β†’ `apps/docs`) -```bash -# App Configuration -NEXT_PUBLIC_APP_NAME="WorkSight" -NEXT_PUBLIC_APP_DESCRIPTION="Employee Well-being Analytics Platform" -NEXT_PUBLIC_APP_URL="https://your-domain.vercel.app" - -# Supabase (if using online auth) -NEXT_PUBLIC_SUPABASE_URL="your-supabase-url" -NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="your-supabase-key" - -# Optional: Analytics -NEXT_PUBLIC_VERCEL_ANALYTICS_ID="your-analytics-id" -NEXT_PUBLIC_GOOGLE_ANALYTICS="your-ga-id" -``` - -### Optional for Offline Mode - -```bash -NEXT_PUBLIC_IS_OFFLINE="true" -``` - -## Vercel Configuration +1. Separate Vercel project from the same repo. +2. **Root Directory** β†’ `apps/docs`. +3. Keep outside-Root-Directory sources enabled. -The `vercel.json` file includes: +Docs may also publish via GitHub Pages; Vercel is optional. -- **Optimized builds** with Next.js -- **Security headers** for production -- **API route configuration** -- **Redirects and rewrites** -- **CORS headers** for API endpoints +### API (`worksight-api` β†’ `apps/api`) -## Code Quality Checks +`apps/api/vercel.json` uses zero-config-style install/build into `dist` (no +legacy `builds`/`routes` block that skipped Vercel's install step). -Before deploying, run quality checks: +**This is still not a functioning serverless API.** `main.ts` calls +`app.listen()` rather than exporting a handler, so a Vercel deployment produces +no invocable function. Until a serverless entry exists, deploy the API with +Docker: ```bash -# Full quality check -pnpm run quality - -# Individual checks -pnpm run type-check # TypeScript validation -pnpm run lint:strict # ESLint with zero warnings -pnpm run prettier:check # Code formatting -pnpm run stylelint:check # CSS/SCSS linting +docker compose up -d --build ``` -## Automated Deployment +## Environment variables -### GitHub Actions +Set in the **Vercel dashboard** (or local `apps/web/.env.local`). Nothing +sensitive belongs in committed `vercel.json`. -- **CI/CD pipeline** runs on every push/PR -- **Code quality gates** prevent bad code from deploying -- **Automatic Vercel deployment** for production and previews - -### Quality Gates - -1. βœ… TypeScript compilation -2. βœ… ESLint (zero warnings) -3. βœ… Prettier formatting -4. βœ… Stylelint CSS validation -5. βœ… Successful build - -## Performance Optimization +```bash +# Web app +NEXT_PUBLIC_APP_NAME="WorkSight" +NEXT_PUBLIC_APP_DESCRIPTION="Employee Well-being Analytics Platform" +NEXT_PUBLIC_APP_URL="https://your-domain.vercel.app" -### Bundle Analysis +# Supabase (optional; skip when offline) +NEXT_PUBLIC_SUPABASE_URL="your-supabase-url" +NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="your-supabase-key" -```bash -# Analyze bundle size before deployment -pnpm run analyze +# Offline / fixture-friendly local mode +NEXT_PUBLIC_IS_OFFLINE="true" ``` -### Build Optimization +Copy from `apps/web/env.example` for local web setup. -- Tree-shaking enabled -- Automatic code splitting -- Image optimization -- Static generation where possible +## Per-app `vercel.json` shape -## Monitoring & Analytics +- **Web:** `framework: nextjs`, `pnpm install --frozen-lockfile`, + `pnpm --filter @worksight/web build`, telemetry disabled for the build. +- **API / docs:** same install/filter pattern; explicit `outputDirectory` + (`dist` / `.vitepress/dist`). -### Vercel Analytics +Security headers, redirects, and CORS are **not** assumed to be present in +`vercel.json` β€” add them when needed. -Automatically enabled with environment variable: +## Pre-deploy checks ```bash -NEXT_PUBLIC_VERCEL_ANALYTICS_ID="your-id" +pnpm install +pnpm --filter @worksight/common build +pnpm type-check +pnpm lint +pnpm format:check +pnpm --filter @worksight/web build +pnpm --filter @worksight/docs build +# API compile (local / Docker path) +pnpm --filter @worksight/api build ``` -### Web Vitals - -Built-in Core Web Vitals monitoring: - -- Largest Contentful Paint (LCP) -- First Input Delay (FID) / Interaction to Next Paint (INP) -- Cumulative Layout Shift (CLS) - -### Error Monitoring - -Error boundaries implemented for graceful error handling. +Use the scripts that actually exist at the repo root (`type-check`, `lint`, +`format:check`, `quality`). There is no root `deploy.yml` workflow and no +`pnpm deploy` / `pnpm analyze` script. -## Domain Configuration +## Automated deployment -### Custom Domain +- **GitHub Actions** run CI (type-check, lint, build gates) on push/PR. +- **Production/preview deploys** for web/docs/api are driven by the linked + **Vercel Git integration** for each project (branch `canary` for production), + not by a root `deploy.yml`. +- Do not expect a single `VERCEL_PROJECT_ID` secret to cover all three apps. -1. Add domain in Vercel dashboard -2. Configure DNS records -3. Update environment variables with new domain +## MVP data honesty -### SSL Certificate - -Automatically provisioned by Vercel for all domains. - -## Security - -### Headers - -- X-Frame-Options: DENY -- X-Content-Type-Options: nosniff -- Referrer-Policy: origin-when-cross-origin -- Permissions-Policy: restrictive - -### Environment Security - -- Never commit `.env.local` files -- Use Vercel environment variables for secrets -- Rotate API keys regularly +- Web MVP views and Nest list/detail endpoints are backed by + **`@worksight/common` fixtures**. +- There is **no** live Supabase persistence for those API endpoints yet. +- Do not document production API keys, webhooks, or hosted `api.worksight.com` + as if they exist. ## Troubleshooting -### Common Issues - -1. **Build Failures** - - ```bash - # Check code quality locally - pnpm run quality - ``` - -2. **Supabase Build Errors** - - If you see "supabaseUrl is required" during build: - - Create `.env.local` with placeholder values: - - ```bash - NEXT_PUBLIC_SUPABASE_URL=https://placeholder.supabase.co - NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=placeholder-key - ``` - - - Or disable Supabase features during build by setting: - - ```bash - NEXT_PUBLIC_IS_OFFLINE=true - ``` - -3. **Environment Variables** - - Ensure all required variables are set in Vercel - - Check variable names match exactly - -4. **Performance Issues** - - ```bash - # Analyze bundle size - pnpm run analyze - ``` - -5. **CI/CD Pipeline Issues** - - GitHub Actions workflow uses `pnpm/action-setup@v4` for proper pnpm - installation - - Deployment jobs are commented out until Vercel secrets are configured - - To enable automatic deployment, configure these secrets in GitHub: - - `VERCEL_TOKEN` - - `VERCEL_ORG_ID` - - `VERCEL_PROJECT_ID` - -### Enabling Automatic Deployment - -To enable automatic Vercel deployment in GitHub Actions: - -1. **Get Vercel Credentials**: - - ```bash - # Install Vercel CLI and login - pnpm add -g vercel - vercel login - - # Link project and get credentials - vercel link - ``` - -2. **Configure GitHub Secrets**: - - Go to GitHub Repository β†’ Settings β†’ Secrets and Variables β†’ Actions - - Add the required secrets (get these from Vercel dashboard or CLI) - -3. **Uncomment Deployment Jobs**: - - Edit `.github/workflows/ci.yml` - - Uncomment the `deploy-preview` and `deploy-production` jobs - -### Support - -- Vercel Documentation: -- Next.js Documentation: - ---- - -## Deployment Checklist - -- [ ] Code quality checks pass -- [ ] Environment variables configured -- [ ] Domain configured (if custom) -- [ ] Analytics setup -- [ ] Error monitoring enabled -- [ ] Performance optimized -- [ ] Security headers verified - -**Your WorkSight application is ready for production! πŸŽ‰** +1. **Build failures** β€” run `pnpm type-check` and rebuild `@worksight/common` + before web/api. +2. **Supabase during build** β€” set placeholders or `NEXT_PUBLIC_IS_OFFLINE=true` + in `.env.local` / Vercel env. +3. **Wrong app built** β€” confirm the Vercel project's Root Directory matches + `apps/web`, `apps/api`, or `apps/docs`. +4. **API "deployed" but dead on Vercel** β€” expected until a serverless handler + exists; use Docker. + +## Checklist + +- [ ] `pnpm type-check` / lint / relevant package builds pass +- [ ] Vercel Root Directory correct per project +- [ ] Dashboard env vars set (no secrets in git) +- [ ] Web preview deploys from `apps/web` +- [ ] API runtime path chosen (Docker today) +- [ ] Docs build (`pnpm --filter @worksight/docs build`) succeeds + +## References + +- Vercel monorepo docs: +- Next.js: +- Repo MVP plan: [docs/mvp/README.md](../docs/mvp/README.md) diff --git a/docs/handoffs/2026-07-25-docs-sync.md b/docs/handoffs/2026-07-25-docs-sync.md index f5b061e..9dae307 100644 --- a/docs/handoffs/2026-07-25-docs-sync.md +++ b/docs/handoffs/2026-07-25-docs-sync.md @@ -1,20 +1,37 @@ # HANDOFF β€” Docs sync (#19) -**Status:** Planned -**Branch:** `feat/mvp-docs` (or fold into docs/mvp-handoffs) +**Status:** Done (MVP slice) +**Branch:** `feat/mvp-docs-19` **Issue(s):** #19 **Last updated:** 2026-07-25 ## Bottom line -README reflects Nest API, Next 15, pnpm/turbo, `@worksight/common` package; handoff index stays linked. + +README, `doc/DEPLOYMENT.md`, VitePress guides/API pages, and MVP/handoff indexes +match Nest + Next 15 + pnpm/Turbo + `@worksight/common` fixtures + three Vercel +projects (`worksight` / `worksight-api` / `worksight-docs`). ## Current state -README still drifts (historical Next 14 / packages β€œfuture”). + +- Root README: package layout includes `apps/api` + `packages/common`; Next 15; + how to run web/api/docs; fixture MVP honesty; no `deploy.yml` / Next 14 myths. +- `doc/DEPLOYMENT.md`: per-app Root Directory table; no serverless Nest handler; + Docker for API; dashboard-only env; scripts that exist. +- VitePress: getting-started / installation / configuration / introduction / + deployment / API overview / auth / user-management rewritten; broken + `survey-endpoints` sidebar link removed; `dev/overview` filled. +- Handoff index links #14–#20. ## Hook points + - Root `README.md` +- `doc/DEPLOYMENT.md` - `docs/mvp/README.md`, `docs/handoffs/README.md` +- `apps/docs/website/guide/*`, `apps/docs/website/dev/api/*` ## Done means -- [ ] No stale stack claims -- [ ] Links to #14–#19 + +- [x] No stale stack claims (Next 14 / packages β€œfuture” / missing API) +- [x] Links to #14–#19 (and #20 deploy handoff) +- [x] Fixture-backed MVP + three Vercel projects documented +- [x] Docs package builds (`pnpm --filter @worksight/docs build`) diff --git a/docs/handoffs/README.md b/docs/handoffs/README.md index b483e09..d560ace 100644 --- a/docs/handoffs/README.md +++ b/docs/handoffs/README.md @@ -1,12 +1,14 @@ # WorkSight handoffs -MVP epic #14. Pattern from complYaigent `docs/handoffs`. +MVP epic [#14](https://github.com/4sightorg/worksight/issues/14). Pattern from +complYaigent `docs/handoffs`. -| Issue | Handoff | -|-------|---------| -| #15 Stabilize | [2026-07-25-stabilize-typecheck.md](./2026-07-25-stabilize-typecheck.md) | -| #16 Wire web | [2026-07-25-wire-web-common.md](./2026-07-25-wire-web-common.md) | -| #17 Wire API | [2026-07-25-wire-api-common.md](./2026-07-25-wire-api-common.md) | -| #18 Demo path | [2026-07-25-demo-path.md](./2026-07-25-demo-path.md) | -| #19 Docs sync | [2026-07-25-docs-sync.md](./2026-07-25-docs-sync.md) | -| #20 Deploy centralization | [2026-07-25-centralize-deployments.md](./2026-07-25-centralize-deployments.md) | +| Issue | Handoff | +| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | +| [#14](https://github.com/4sightorg/worksight/issues/14) Epic | [docs/mvp/README.md](../mvp/README.md) | +| [#15](https://github.com/4sightorg/worksight/issues/15) Stabilize | [2026-07-25-stabilize-typecheck.md](./2026-07-25-stabilize-typecheck.md) | +| [#16](https://github.com/4sightorg/worksight/issues/16) Wire web | [2026-07-25-wire-web-common.md](./2026-07-25-wire-web-common.md) | +| [#17](https://github.com/4sightorg/worksight/issues/17) Wire API | [2026-07-25-wire-api-common.md](./2026-07-25-wire-api-common.md) | +| [#18](https://github.com/4sightorg/worksight/issues/18) Demo path | [2026-07-25-demo-path.md](./2026-07-25-demo-path.md) | +| [#19](https://github.com/4sightorg/worksight/issues/19) Docs sync | [2026-07-25-docs-sync.md](./2026-07-25-docs-sync.md) | +| [#20](https://github.com/4sightorg/worksight/issues/20) Deploy centralization | [2026-07-25-centralize-deployments.md](./2026-07-25-centralize-deployments.md) | diff --git a/docs/mvp/README.md b/docs/mvp/README.md index 57ab4b5..48576c2 100644 --- a/docs/mvp/README.md +++ b/docs/mvp/README.md @@ -2,37 +2,50 @@ > **Date:** 2026-07-25 > **Repo:** [4sightorg/worksight](https://github.com/4sightorg/worksight) -> **Local:** `/home/kaoru/work/4sight/worksight` -> **Status:** Plan to build (MVP) +> **Status:** In progress (MVP) > **Epic:** [#14 MVP: WorkSight running on @worksight/common data layer](https://github.com/4sightorg/worksight/issues/14) -> **Base tip:** `fix/restore-install-build-canary` (pnpm cutover in flight) +> **Base +> tip:** `feat/mvp-stabilize` (pnpm + Turbo; stacked PRs #21–#24) ## Problem -`@worksight/common` already has **types / data / utils** (employees, tasks, survey, burnout, datasources), but the product surface is mostly a landing page. Web type-check fails on Jest globals in tests. Goal: **MVP that actually runs on the common data classes**. + +`@worksight/common` already has **types / data / utils** (employees, tasks, +survey, burnout, datasources). The MVP goal is a product surface that **runs on +those fixtures** (web + Nest), with honest docs and deploy layout β€” not live +external connectors or full Supabase persistence for the new API routes. ## Definition of Done -- [ ] common + web + api type-check/build green -- [ ] Web dashboards consume `@worksight/common` fixtures/utils -- [ ] API shapes align with common types -- [ ] Documented demo path shows populated well-being/task views -- [ ] README matches Nest + Next 15 + packages reality + +- [x] common + web + api type-check/build green (stabilize / stacked PRs) +- [ ] Web dashboards consume `@worksight/common` fixtures/utils (#16 / PR #22) +- [ ] API shapes align with common types (#17 / PR #24) +- [ ] Documented demo path shows populated well-being/task views (#18) +- [ ] README matches Nest + Next 15 + packages reality (#19) - [ ] Handoffs for each workstream +- [ ] Uniform per-app Vercel configs (#20 / PR #23) ## Workstreams β†’ issues -| # | Workstream | Issue | Pri | -|---|------------|-------|-----| -| W1 | Stabilize install / type-check / common build | [#15](https://github.com/4sightorg/worksight/issues/15) | P0 | -| W2 | Wire web β†’ common data/types/utils | [#16](https://github.com/4sightorg/worksight/issues/16) | P0 | -| W3 | Wire API β†’ common types | [#17](https://github.com/4sightorg/worksight/issues/17) | P0 | -| W4 | E2E demo path | [#18](https://github.com/4sightorg/worksight/issues/18) | P1 | -| W5 | Docs sync | [#19](https://github.com/4sightorg/worksight/issues/19) | P1 | -| W6 | Centralize deployments | [#20](https://github.com/4sightorg/worksight/issues/20) | P1 | +| # | Workstream | Issue | Pri | +| --- | --------------------------------------------- | ------------------------------------------------------- | --- | +| W1 | Stabilize install / type-check / common build | [#15](https://github.com/4sightorg/worksight/issues/15) | P0 | +| W2 | Wire web β†’ common data/types/utils | [#16](https://github.com/4sightorg/worksight/issues/16) | P0 | +| W3 | Wire API β†’ common types | [#17](https://github.com/4sightorg/worksight/issues/17) | P0 | +| W4 | E2E demo path | [#18](https://github.com/4sightorg/worksight/issues/18) | P1 | +| W5 | Docs sync | [#19](https://github.com/4sightorg/worksight/issues/19) | P1 | +| W6 | Centralize deployments | [#20](https://github.com/4sightorg/worksight/issues/20) | P1 | -**Suggested order:** W1 β†’ W2βˆ₯W3 β†’ W4 β†’ W5. +**Suggested order:** W1 β†’ W2βˆ₯W3 β†’ W4 β†’ W5 (docs can track wiring/deploy facts +from open PRs). W6 may land in parallel with docs. ## Non-goals -Live external connectors (Jira/Trello/GitHub/Odoo/Slack); production auth hardening; docs site polish beyond honesty. + +Live external connectors (Jira/Trello/GitHub/Odoo/Slack); production auth +hardening; docs site polish beyond honesty; claiming Supabase persistence or a +serverless Nest handler before they exist. ## Handoffs -See [../handoffs/](../handoffs/). + +See [../handoffs/](../handoffs/) β€” index links +[#15](https://github.com/4sightorg/worksight/issues/15)–[#20](https://github.com/4sightorg/worksight/issues/20) +(parent epic [#14](https://github.com/4sightorg/worksight/issues/14)).