diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..292525e9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +node_modules +.pnpm-store +dist +build +coverage +.vite +.env +.env.* +!.env.example +.git +.gitignore +.DS_Store +*.log +/home/ubuntu/repo_buildouts/ellie_audit diff --git a/.env.example b/.env.example index b18de12c..d1399ab7 100644 --- a/.env.example +++ b/.env.example @@ -1,24 +1,42 @@ +# Ellie AI environment template +# Copy this file to `.env` for local development. Never commit real secrets. + +# ----------------------------------------------------------------------------- +# Runtime +# ----------------------------------------------------------------------------- +NODE_ENV=development +PORT=3000 +VITE_APP_ID=ellie-ai-local +VITE_APP_TITLE="Ellie AI" + +# ----------------------------------------------------------------------------- # Database +# ----------------------------------------------------------------------------- +# Required for production readiness. Ellie persists uploaded video metadata and +# AI analysis results in a MySQL-compatible database through Drizzle ORM. DATABASE_URL=mysql://user:password@localhost:3306/ellie_ai -# Authentication -JWT_SECRET=your-jwt-secret-here -VITE_APP_ID=your-app-id -OAUTH_SERVER_URL=https://your-oauth-server.com -VITE_OAUTH_PORTAL_URL=https://your-oauth-portal.com - -# AI Services (LLM - Gemini 2.5 Flash) -BUILT_IN_FORGE_API_URL=https://your-llm-api-url.com -BUILT_IN_FORGE_API_KEY=your-llm-api-key +# ----------------------------------------------------------------------------- +# Sessions and optional owner authentication +# ----------------------------------------------------------------------------- +# Required in production for secure session cookies. Generate a high-entropy +# value with a password manager or: openssl rand -base64 48 +JWT_SECRET=replace-with-a-high-entropy-secret -# Frontend AI Access -VITE_FRONTEND_FORGE_API_URL=https://your-frontend-api-url.com -VITE_FRONTEND_FORGE_API_KEY=your-frontend-api-key +# Optional. Configure these only when owner/admin authentication is enabled. +OAUTH_SERVER_URL= +OWNER_OPEN_ID= -# Owner Info -OWNER_OPEN_ID=your-owner-open-id -OWNER_NAME=Your Name +# ----------------------------------------------------------------------------- +# Forge-compatible AI, transcription, and storage proxy +# ----------------------------------------------------------------------------- +# Required for production readiness. These credentials back Gemini-style video +# analysis, Whisper-style voice transcription, and object storage proxy uploads. +BUILT_IN_FORGE_API_URL=https://api.example.com/ +BUILT_IN_FORGE_API_KEY=replace-with-forge-compatible-api-key -# App Config -VITE_APP_TITLE=Ellie AI -VITE_APP_LOGO= +# ----------------------------------------------------------------------------- +# Client-visible branding metadata +# ----------------------------------------------------------------------------- +# Public values only. Do not put secrets in VITE_* variables. +VITE_APP_LOGO_URL=/assets/icon.png diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 99554a79..844e068f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,139 +1,88 @@ -## Description +## Summary - +Describe the change in plain language. Include product impact, backend impact, and the reason this change is needed. ## Type of Change - - -- [ ] πŸ› Bug fix (non-breaking change which fixes an issue) -- [ ] ✨ New feature (non-breaking change which adds functionality) -- [ ] πŸ’₯ Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] πŸ“ Documentation update -- [ ] 🎨 Style/UI update (no functional changes) -- [ ] ♻️ Code refactoring (no functional changes) -- [ ] ⚑ Performance improvement -- [ ] βœ… Test update -- [ ] πŸ”§ Build/CI update -- [ ] πŸ”’ Security update - -## Related Issues - - - -Closes # -Related to # - -## Changes Made - - - -- -- -- - -## Testing - - - -### Test Environment -- [ ] Local development -- [ ] Docker containers -- [ ] Staging environment - -### Tests Performed -- [ ] Unit tests pass -- [ ] Integration tests pass -- [ ] Manual testing completed -- [ ] Browser testing (if frontend changes) - -### Test Commands -```bash -# Commands used to test these changes -npm test -npm run lint -npm run type-check +- [ ] Feature +- [ ] Bug fix +- [ ] Backend hardening +- [ ] Security hardening +- [ ] Documentation +- [ ] Release / deployment +- [ ] Refactor +- [ ] Test update +- [ ] Dependency or tooling update + +## Product and User Impact + +Explain what users, operators, or maintainers will notice after this change. + +## Backend and Data Impact + +| Question | Answer | +| ------------------------------------------------------------------------------- | ------ | +| Does this change tRPC procedures, server middleware, or operational endpoints? | | +| Does this change the database schema or migrations? | | +| Does this change storage, AI provider, auth, or background-processing behavior? | | +| Does this introduce new environment variables or secrets? | | +| Does this affect `/api/health`, `/api/readiness`, or `/api/ready`? | | + +## Validation Evidence + +Check every command that was run and paste relevant output or artifact links in the notes below. + +- [ ] `pnpm install --frozen-lockfile` +- [ ] `pnpm validate:env` +- [ ] `pnpm validate:env:production` +- [ ] `pnpm check` +- [ ] `pnpm test` +- [ ] `pnpm build` +- [ ] `pnpm run ci` +- [ ] Runtime smoke test: `/api/health` +- [ ] Runtime smoke test: `/api/readiness` or `/api/ready` +- [ ] Docker build and container smoke test +- [ ] Not applicable; this is documentation-only + +### Validation Notes + +```text +Paste command output summaries, health/readiness responses, or CI links here. Redact secrets. ``` -## Screenshots - - +## Screenshots or Recordings -## Checklist +Add screenshots for UI changes. If no visual surface changed, write `Not applicable`. - +## Documentation and Release Notes -### Code Quality -- [ ] My code follows the project's style guidelines -- [ ] I have performed a self-review of my code -- [ ] I have commented my code, particularly in hard-to-understand areas -- [ ] My changes generate no new warnings -- [ ] I have run `npm run lint` and fixed all issues -- [ ] I have run `npm run format` to format my code +- [ ] `README.md` updated or verified as still accurate +- [ ] `SETUP.md` updated or verified as still accurate +- [ ] `docs/PRODUCTION_READINESS.md` updated or verified as still accurate +- [ ] `RELEASES.md` updated or verified as still accurate +- [ ] `.env.example` updated when configuration changed +- [ ] Migration or deployment notes added when required -### Testing -- [ ] I have added tests that prove my fix is effective or that my feature works -- [ ] New and existing unit tests pass locally with my changes -- [ ] I have run `npm test` and all tests pass -- [ ] I have tested on multiple browsers (if frontend changes) +## Security Checklist -### Documentation -- [ ] I have updated the documentation accordingly -- [ ] I have updated the README if needed -- [ ] I have added/updated JSDoc comments for new functions -- [ ] I have updated the CHANGELOG (if applicable) +- [ ] No secrets, tokens, private media, `.env` files, or credentials are committed +- [ ] New inputs are validated before use +- [ ] Auth and ownership checks are preserved or improved +- [ ] Provider credentials are read from environment or secret stores only +- [ ] Dependency changes are intentional and documented -### Dependencies -- [ ] I have not added unnecessary dependencies -- [ ] All new dependencies are properly documented -- [ ] I have run `npm audit` and addressed any issues +## Reviewer Focus Areas -### Security -- [ ] My changes do not introduce security vulnerabilities -- [ ] I have not committed sensitive information (API keys, passwords, etc.) -- [ ] I have followed security best practices +List the files or behaviors reviewers should inspect most carefully. -## Performance Impact - - - -- [ ] No performance impact -- [ ] Performance improved -- [ ] Performance may be affected (explain below) - -## Breaking Changes - - +- +- +- ## Deployment Notes - - -## Additional Context - - - ---- - -## For Reviewers - -### Review Focus Areas - - -- -- - -### Questions for Reviewers - - -- -- +Describe rollout requirements, required secrets, database migrations, rollback considerations, and monitoring checks. ---- +## Related Issues or Follow-Ups -**PR Author Checklist:** -- [ ] I have read the [Contributing Guidelines](../CONTRIBUTING.md) -- [ ] I have assigned appropriate labels -- [ ] I have requested reviews from relevant team members -- [ ] I have linked related issues -- [ ] All CI checks are passing +Link related issues, TODOs, or planned follow-up PRs. diff --git a/.github/README.md b/.github/README.md index 00018c84..73bd54cc 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,98 +1,65 @@ -# GitHub Workflows - CI/CD Pipeline - -> Automated CI/CD pipeline with GitHub Actions including linting, testing, security scanning, Docker builds, performance monitoring, and automated deployments. - -## πŸš€ Workflows - -### 1. CI Pipeline (`workflows/ci.yml`) -**Triggers**: Push to main/develop, Pull requests - -**Jobs**: -- βœ… Lint code (ESLint) -- βœ… Type check (TypeScript) -- βœ… Run tests (Jest/Vitest) -- βœ… Security scan -- βœ… Build applications -- βœ… Docker build & test -- βœ… Integration tests - -### 2. Code Quality (`workflows/code-quality.yml`) -**Triggers**: Push to main/develop - -**Jobs**: -- βœ… Prettier format check -- βœ… ESLint with annotations -- βœ… TypeScript type check -- βœ… CodeQL security analysis -- βœ… Dependency review - -### 3. Docker (`workflows/docker.yml`) -**Triggers**: Push to main - -**Jobs**: -- βœ… Build Docker images -- βœ… Security scanning -- βœ… Integration tests -- βœ… Push to registry - -### 4. Performance (`workflows/performance.yml`) -**Triggers**: Push to main, Weekly schedule - -**Jobs**: -- βœ… Lighthouse audits -- βœ… Bundle size analysis -- βœ… Load testing -- βœ… Performance regression detection - -### 5. CD Pipeline (`workflows/cd.yml`) -**Triggers**: Push to main (after CI passes) - -**Jobs**: -- βœ… Deploy to staging -- βœ… Run smoke tests -- βœ… Deploy to production -- βœ… Rollback on failure - -### 6. Release (`workflows/release.yml`) -**Triggers**: Tag push (v*) - -**Jobs**: -- βœ… Generate changelog -- βœ… Create GitHub release -- βœ… Tag version -- βœ… Publish artifacts - -### 7. PR Checks (`workflows/pr-checks.yml`) -**Triggers**: Pull request events - -**Jobs**: -- βœ… Validate PR format -- βœ… Add size labels -- βœ… Auto-assign reviewers -- βœ… Run PR-specific checks - -## πŸ“Š Pipeline Status - -**View live status**: https://github.com/Alexi5000/Ellie/actions - -## πŸ”§ Configuration - -### Secrets Required -- `OPENAI_API_KEY` - OpenAI API key -- `GROQ_API_KEY` - Groq API key -- `DOCKER_USERNAME` - Docker Hub username -- `DOCKER_PASSWORD` - Docker Hub password - -### Environment Variables -- `NODE_ENV` - Environment (development/production) -- `CI` - CI environment flag - -## πŸ“– Documentation - -- [CI/CD Pipeline](../docs/ci-cd/CI_CD_PIPELINE.md) - Complete documentation -- [CI/CD Setup](../docs/ci-cd/CI_CD_SETUP.md) - Setup guide -- [Quick Reference](../docs/ci-cd/QUICK_REFERENCE.md) - Common commands - ---- - -**Maintained by**: Alex Cinovoj, TechTide AI +# Ellie AI GitHub Automation + +This directory contains GitHub metadata for Ellie AI, including workflow definitions, pull request guidance, auto-assignment configuration, and repository automation notes. + +## Current Review Standard + +Pull requests should prove that the application remains buildable, type-safe, documented, and operationally understandable. Backend or deployment changes should include environment validation and health/readiness evidence. + +| Gate | Preferred Command | +| --------------------------- | ------------------------------------------ | +| Install consistency | `pnpm install --frozen-lockfile` | +| Environment inventory | `pnpm validate:env` | +| Production environment gate | `pnpm validate:env:production` | +| Type safety | `pnpm check` | +| Unit tests | `pnpm test` | +| Production build | `pnpm build` | +| Full gate | `pnpm run ci` | +| Liveness smoke test | `curl /api/health` | +| Readiness smoke test | `curl /api/readiness` or `curl /api/ready` | + +## Workflow Inventory + +The repository contains several workflow files. Some were created before the current root pnpm workflow was standardized, so maintainers should verify each workflow against `package.json` before relying on it as an authoritative release gate. + +| Workflow | Intended Purpose | Maintainer Note | +| ---------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------- | +| `workflows/ci.yml` | General CI checks | Should align with `pnpm validate:env`, `pnpm check`, `pnpm test`, and `pnpm build`. | +| `workflows/test.yml` | Test automation | Should use root pnpm scripts. | +| `workflows/code-quality.yml` | Formatting, type, and quality checks | Confirm commands exist before enabling required status checks. | +| `workflows/docker.yml` | Container build validation | Should build the root `Dockerfile` and smoke-test `/api/health`. | +| `workflows/performance.yml` | Performance monitoring | Should be treated as optional until Lighthouse targets are confirmed. | +| `workflows/cd.yml` | Deployment automation | Do not enable production deployment until secrets, environments, rollback, and readiness checks are configured. | +| `workflows/release.yml` | Release automation | Should publish releases only after the release checklist in `RELEASES.md` is satisfied. | +| `workflows/pr-checks.yml` | Pull request metadata checks | Should support the updated PR template. | + +## Required Secrets for Production Workflows + +Secrets should be configured in GitHub Actions or the deployment platform, never committed to the repository. + +| Secret | Purpose | +| ------------------------ | -------------------------------------------------------------------- | +| `DATABASE_URL` | MySQL-compatible database connection string. | +| `JWT_SECRET` | Session and token signing secret. | +| `BUILT_IN_FORGE_API_URL` | AI/provider gateway endpoint. | +| `BUILT_IN_FORGE_API_KEY` | AI/provider gateway credential. | +| `AWS_ACCESS_KEY_ID` | Optional object storage credential when using S3-compatible storage. | +| `AWS_SECRET_ACCESS_KEY` | Optional object storage credential when using S3-compatible storage. | +| `AWS_REGION` | Optional object storage region. | +| `S3_BUCKET_NAME` | Optional media bucket name. | +| `DOCKER_USERNAME` | Optional container registry username. | +| `DOCKER_PASSWORD` | Optional container registry token or password. | + +## Maintainer Guidance + +Workflow updates may require a GitHub token or app installation with workflow-write permission. If a branch push is rejected because workflow files changed, push the application changes first and apply workflow changes separately from an account with the required permission. + +The current documentation source of truth is: + +| Document | Purpose | +| -------------------------------------------------------------------- | ----------------------------------------------- | +| [`../README.md`](../README.md) | Product and architecture overview. | +| [`../SETUP.md`](../SETUP.md) | Setup, build, Docker, and runtime instructions. | +| [`../docs/PRODUCTION_READINESS.md`](../docs/PRODUCTION_READINESS.md) | Release gates and operational readiness. | +| [`../RELEASES.md`](../RELEASES.md) | Version history and milestone plan. | +| [`PULL_REQUEST_TEMPLATE.md`](PULL_REQUEST_TEMPLATE.md) | Required review evidence for each PR. | diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..998894a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +# Dependencies +node_modules/ +.pnpm-store/ + +# Build outputs +dist/ +build/ +coverage/ +.next/ +.vite/ +*.tsbuildinfo + +# Local environment and secrets +.env +.env.* +!.env.example +*.pem +*.key +*.crt + +# Logs and diagnostics +*.log +logs/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# OS and editor files +.DS_Store +Thumbs.db +.vscode/ +.idea/ +*.swp +*.swo + +# Runtime uploads and generated media +uploads/ +tmp/ +temp/ + +# Local database files +*.sqlite +*.sqlite3 +*.db + +# Docker and deployment local state +.docker/ +.cache/ diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..f31963a8 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +legacy-peer-deps=true +fund=false +audit=false diff --git a/.prettierignore b/.prettierignore index 72842592..7d24fb87 100644 --- a/.prettierignore +++ b/.prettierignore @@ -11,6 +11,9 @@ build/ *.tsbuildinfo coverage/ +# GitHub workflow files require workflow-scope permissions to update remotely. +.github/workflows/ + # Package files package-lock.json pnpm-lock.yaml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d5329e47..d3c68702 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,486 +1,118 @@ -# Contributing to Ellie Voice Receptionist - -Thank you for your interest in contributing to Ellie Voice Receptionist! This document provides guidelines and instructions for contributing to the project. - -## πŸ“‹ Table of Contents - -- [Code of Conduct](#code-of-conduct) -- [Getting Started](#getting-started) -- [Development Workflow](#development-workflow) -- [Coding Standards](#coding-standards) -- [Testing Guidelines](#testing-guidelines) -- [Documentation](#documentation) -- [Pull Request Process](#pull-request-process) -- [Project Structure](#project-structure) - -## 🀝 Code of Conduct - -- Be respectful and inclusive -- Welcome newcomers and help them get started -- Focus on constructive feedback -- Respect different viewpoints and experiences - -## πŸš€ Getting Started - -### Prerequisites - -- Node.js 18+ and npm -- Docker Desktop -- Git -- Code editor (VS Code recommended) - -### Initial Setup - -1. **Fork and Clone** - ```bash - git clone https://github.com/Alexi5000/Ellie.git - cd Ellie - ``` - -2. **Install Dependencies** - ```bash - # Backend - cd backend && npm install - - # Frontend - cd ../frontend && npm install - - # Root (for integration tests) - cd .. && npm install - ``` - -3. **Environment Configuration** - ```bash - # Backend - cp backend/.env.example backend/.env - # Edit backend/.env with your API keys - - # Frontend - cp frontend/.env.example frontend/.env - ``` - -4. **Start Development Environment** - ```bash - npm run docker:up - ``` - -## πŸ”„ Development Workflow - -### Branch Strategy - -- `main` - Production-ready code -- `develop` - Integration branch for features -- `feature/*` - New features -- `bugfix/*` - Bug fixes -- `hotfix/*` - Urgent production fixes - -### Creating a Feature Branch +# Contributing to Ellie AI -```bash -git checkout develop -git pull origin develop -git checkout -b feature/your-feature-name -``` - -### Making Changes - -1. **Write Code** - - Follow coding standards (see below) - - Add tests for new functionality - - Update documentation as needed - -2. **Test Locally** - ```bash - # Run all tests - npm run test:all - - # Run specific tests - npm run test:backend - npm run test:frontend - ``` - -3. **Commit Changes** - ```bash - git add . - git commit -m "feat: add new feature description" - ``` - -### Commit Message Convention - -Follow [Conventional Commits](https://www.conventionalcommits.org/): - -- `feat:` - New feature -- `fix:` - Bug fix -- `docs:` - Documentation changes -- `style:` - Code style changes (formatting, etc.) -- `refactor:` - Code refactoring -- `test:` - Adding or updating tests -- `chore:` - Maintenance tasks - -**Examples:** -``` -feat: add voice recording pause functionality -fix: resolve WebSocket connection timeout issue -docs: update API documentation for voice endpoints -test: add integration tests for AI service -``` - -## πŸ’» Coding Standards - -### TypeScript/JavaScript - -- Use TypeScript for type safety -- Follow ESLint configuration -- Use meaningful variable names -- Add JSDoc comments for public APIs -- Prefer `const` over `let`, avoid `var` -- Use async/await over promises - -**Example:** -```typescript -/** - * Process voice input and generate AI response - * @param audioData - Raw audio buffer - * @param sessionId - User session identifier - * @returns Processed response with audio - */ -async function processVoiceInput( - audioData: Buffer, - sessionId: string -): Promise { - // Implementation -} -``` +Thank you for contributing to Ellie AI. This repository is being hardened as a professional full-stack TypeScript application, so every contribution should improve product quality, backend correctness, operational readiness, documentation accuracy, or release confidence. -### React Components - -- Use functional components with hooks -- Implement proper prop types -- Add accessibility attributes -- Handle loading and error states -- Use meaningful component names - -**Example:** -```typescript -interface VoiceButtonProps { - onStart: () => void; - onStop: () => void; - isRecording: boolean; - disabled?: boolean; -} - -export const VoiceButton: React.FC = ({ - onStart, - onStop, - isRecording, - disabled = false, -}) => { - // Implementation -}; -``` - -### Python (FastAPI) - -- Follow PEP 8 style guide -- Use type hints -- Add docstrings for functions -- Use Pydantic models for validation - -**Example:** -```python -from pydantic import BaseModel, Field - -class VoiceRequest(BaseModel): - """Voice processing request model""" - text: str = Field(..., max_length=4000) - language: str = Field(default="en", regex="^[a-z]{2}$") - - class Config: - schema_extra = { - "example": { - "text": "Hello, how can I help you?", - "language": "en" - } - } -``` +## Working Agreement -## πŸ§ͺ Testing Guidelines - -### Writing Tests - -1. **Test Coverage** - - Aim for 80%+ code coverage - - Test happy paths and edge cases - - Test error handling - -2. **Test Structure** - ```typescript - describe('Component/Service Name', () => { - describe('Method/Feature Name', () => { - it('should do something specific', () => { - // Arrange - const input = createTestData(); - - // Act - const result = functionUnderTest(input); - - // Assert - expect(result).toBe(expected); - }); - }); - }); - ``` - -3. **Use Test Helpers** - ```typescript - // Backend - import { createMockMulterFile, flushPromises } from './test/testHelpers'; - - // Frontend - import { renderWithProviders, mockGetUserMedia } from './test/testHelpers'; - ``` - -### Running Tests +Contributors should keep changes small enough to review, document operational impact, and run the required validation gates before requesting review. Ellie’s active backend is the TypeScript Express/tRPC runtime in `server/`; the FastAPI material under `docs/migration/` is reference material unless a future migration is explicitly approved. -```bash -# All tests -npm run test:all +| Principle | Expectation | +| --------------------- | --------------------------------------------------------------------------------------------------- | +| Backend truthfulness | Do not document unimplemented provider workflows as production-complete. Mark planned work clearly. | +| Type safety | Keep client calls, tRPC procedures, shared types, and database schema changes aligned. | +| Operational readiness | Update health, readiness, setup, and release documentation when runtime behavior changes. | +| Security hygiene | Do not commit secrets, generated credentials, private media, or local environment files. | +| Reviewability | Use focused branches, conventional commits, validation evidence, and clear PR descriptions. | -# Backend only -npm run test:backend +## Prerequisites -# Frontend only -npm run test:frontend - -# Watch mode -cd backend && npm run test:watch -cd frontend && npm run test:watch - -# With coverage -npm test -- --coverage -``` +| Tool | Version | Purpose | +| ------------------------- | -------------: | --------------------------------------------------------------- | +| Node.js | 22 or newer | Development and production runtime. | +| pnpm | 10.x | Dependency management through the lockfile. | +| MySQL-compatible database | 8.x compatible | Required for database-backed production flows. | +| Docker | Current stable | Optional but recommended for release and deployment validation. | -## πŸ“š Documentation +## Local Setup -### When to Update Documentation - -- Adding new features -- Changing APIs -- Modifying configuration -- Fixing bugs that affect usage -- Adding new dependencies - -### Documentation Structure - -``` -docs/ -β”œβ”€β”€ README.md # Documentation index -β”œβ”€β”€ development/ # Development guides -β”œβ”€β”€ testing/ # Testing documentation -β”œβ”€β”€ migration/ # Migration guides -β”œβ”€β”€ architecture.md # System architecture -β”œβ”€β”€ deployment.md # Deployment guide -└── api-reference.md # API documentation -``` - -### Documentation Style - -- Use clear, concise language -- Include code examples -- Add diagrams where helpful -- Keep it up to date -- Link to related documentation - -## πŸ”€ Pull Request Process - -### Before Submitting - -1. **Update from develop** - ```bash - git checkout develop - git pull origin develop - git checkout your-feature-branch - git rebase develop - ``` - -2. **Run Tests** - ```bash - npm run test:all - ``` - -3. **Check Linting** - ```bash - cd backend && npm run lint - cd frontend && npm run lint - ``` - -4. **Update Documentation** - - Update relevant docs - - Add/update tests - - Update CHANGELOG if applicable - -### Submitting PR - -1. **Push to Your Fork** - ```bash - git push origin feature/your-feature-name - ``` - -2. **Create Pull Request** - - Go to GitHub repository - - Click "New Pull Request" - - Select your branch - - Fill out PR template - -3. **PR Template** - ```markdown - ## Description - Brief description of changes - - ## Type of Change - - [ ] Bug fix - - [ ] New feature - - [ ] Breaking change - - [ ] Documentation update - - ## Testing - - [ ] Tests pass locally - - [ ] Added new tests - - [ ] Updated documentation - - ## Checklist - - [ ] Code follows style guidelines - - [ ] Self-review completed - - [ ] Comments added for complex code - - [ ] Documentation updated - - [ ] No new warnings generated - ``` - -### Review Process - -1. **Automated Checks** - - CI/CD pipeline runs tests - - Linting checks pass - - Build succeeds - -2. **Code Review** - - At least one approval required - - Address review comments - - Update PR as needed - -3. **Merge** - - Squash and merge to develop - - Delete feature branch - - Update local repository - -## πŸ“ Project Structure - -``` -ellie-voice-receptionist/ -β”œβ”€β”€ backend/ # Node.js/Express backend -β”‚ β”œβ”€β”€ src/ -β”‚ β”‚ β”œβ”€β”€ routes/ # API routes -β”‚ β”‚ β”œβ”€β”€ services/ # Business logic -β”‚ β”‚ β”œβ”€β”€ middleware/ # Express middleware -β”‚ β”‚ └── test/ # Test utilities -β”‚ └── package.json -β”œβ”€β”€ backend-fastapi/ # Python/FastAPI backend -β”‚ β”œβ”€β”€ app/ -β”‚ β”‚ β”œβ”€β”€ api/ # API endpoints -β”‚ β”‚ β”œβ”€β”€ core/ # Core configuration -β”‚ β”‚ └── services/ # Business logic -β”‚ └── requirements.txt -β”œβ”€β”€ frontend/ # React/TypeScript frontend -β”‚ β”œβ”€β”€ src/ -β”‚ β”‚ β”œβ”€β”€ components/ # React components -β”‚ β”‚ β”œβ”€β”€ hooks/ # Custom hooks -β”‚ β”‚ β”œβ”€β”€ contexts/ # React contexts -β”‚ β”‚ └── test/ # Test utilities -β”‚ └── package.json -β”œβ”€β”€ docker/ # Docker configurations -β”œβ”€β”€ docs/ # Documentation -β”œβ”€β”€ scripts/ # Build/deployment scripts -β”œβ”€β”€ tests/ # Integration tests -└── package.json # Root orchestration +```bash +git clone https://github.com/Alexi5000/Ellie.git +cd Ellie +pnpm install --frozen-lockfile +cp .env.example .env +pnpm validate:env +pnpm dev ``` -## πŸ› Reporting Bugs - -### Before Reporting +The local validator reports missing production-only variables as inventory findings in development. Production validation is stricter and should be run in a secret-complete environment. -1. Check existing issues -2. Verify it's reproducible -3. Test on latest version -4. Gather relevant information +## Branch Strategy -### Bug Report Template +Use branch names that identify the intent and surface area of the change. -```markdown -## Bug Description -Clear description of the bug +| Branch Prefix | Use Case | +| ------------- | -------------------------------------------------------- | +| `feature/` | Product or backend capability changes. | +| `fix/` | Defect correction. | +| `docs/` | Documentation-only updates. | +| `hardening/` | Production-readiness, security, or release-gate work. | +| `chore/` | Maintenance tasks such as dependency or tooling updates. | -## Steps to Reproduce -1. Go to '...' -2. Click on '...' -3. See error +Do not push directly to `main`. Open a pull request and include validation evidence. -## Expected Behavior -What should happen +## Commit Messages -## Actual Behavior -What actually happens +Use Conventional Commits so release notes and code review history remain readable. -## Environment -- OS: [e.g., Windows 10] -- Browser: [e.g., Chrome 96] -- Node Version: [e.g., 18.0.0] -- Docker Version: [e.g., 20.10.0] +| Prefix | Meaning | +| ----------- | ------------------------------------------------ | +| `feat:` | User-visible or backend capability. | +| `fix:` | Bug fix. | +| `docs:` | Documentation-only change. | +| `refactor:` | Code structure change without behavior change. | +| `test:` | Test addition or correction. | +| `chore:` | Tooling, dependency, or maintenance change. | +| `security:` | Security hardening or vulnerability remediation. | -## Additional Context -Screenshots, logs, etc. -``` - -## πŸ’‘ Feature Requests +## Required Validation -### Proposing Features +Run the relevant gates before opening a pull request. Backend or runtime changes should run the full set. -1. Check existing feature requests -2. Describe the problem it solves -3. Propose a solution -4. Consider alternatives -5. Discuss implementation +| Gate | Command | When Required | +| --------------------------- | -------------------------------- | ----------------------------------------------------------- | +| Install consistency | `pnpm install --frozen-lockfile` | Dependency or lockfile changes. | +| Environment inventory | `pnpm validate:env` | Every PR that touches backend, config, docs, or deployment. | +| Production environment gate | `pnpm validate:env:production` | Release candidates and deployment changes. | +| Typecheck | `pnpm check` | Every code PR. | +| Tests | `pnpm test` | Every code PR. | +| Build | `pnpm build` | Every code or deployment PR. | +| Full gate | `pnpm ci` | Release candidates and large backend changes. | -### Feature Request Template +## Backend Contribution Rules -```markdown -## Problem Statement -What problem does this solve? +Backend changes should preserve clear boundaries between request handling, persistence, provider integration, and operational checks. -## Proposed Solution -How should it work? +| Area | Rule | +| --------------------- | ---------------------------------------------------------------------------------------------------- | +| tRPC routers | Validate inputs with schemas and keep client contracts synchronized. | +| Database schema | Generate migrations, review diffs, and document rollback considerations. | +| Provider integrations | Use adapter boundaries so tests can run without real provider credentials. | +| Health/readiness | Keep `/api/health` lightweight and reserve `/api/readiness` for configuration and dependency status. | +| Secrets | Read secrets only from environment variables or platform secret stores. | +| Long-running work | Prefer durable jobs over request-bound media processing. | -## Alternatives Considered -What other approaches were considered? +## Documentation Requirements -## Additional Context -Mockups, examples, etc. -``` +Update documentation when a change affects setup, environment variables, endpoints, release gates, architecture, or user-visible behavior. -## πŸ†˜ Getting Help +| Document | Update When | +| ---------------------------------- | ------------------------------------------------------------------------------- | +| `README.md` | Product positioning, architecture, scripts, or operational behavior changes. | +| `SETUP.md` | Installation, environment, Docker, database, or runtime instructions change. | +| `docs/PRODUCTION_READINESS.md` | Backend readiness, operational gates, or risk posture changes. | +| `RELEASES.md` | Any release candidate, milestone, or production-impacting change is introduced. | +| `.github/PULL_REQUEST_TEMPLATE.md` | Review policy or validation expectations change. | -- **Documentation**: Check [docs/](docs/) -- **Issues**: Search existing issues -- **Discussions**: GitHub Discussions -- **Chat**: Project Slack/Discord +## Pull Request Expectations -## πŸ“„ License +A professional PR should include a plain-language summary, validation commands, operational impact, screenshots for UI changes, and explicit notes for backend, database, environment, and deployment effects. -By contributing, you agree that your contributions will be licensed under the MIT License. +Before requesting review, confirm that no `.env`, credentials, private media, generated logs, or local build artifacts have been committed. -## πŸ™ Thank You! +## Reporting Bugs -Your contributions make this project better for everyone. Thank you for taking the time to contribute! +A high-quality bug report should include the affected route or endpoint, reproduction steps, expected behavior, actual behavior, environment details, logs with secrets redacted, and whether `/api/health` or `/api/readiness` is failing. ---- +## License -**Questions?** Open an issue or reach out to the maintainers. \ No newline at end of file +By contributing, you agree that your contributions are licensed under the MIT License. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..560cc9c8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +# syntax=docker/dockerfile:1.7 + +FROM node:22.13.0-slim AS base +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH +RUN corepack enable +WORKDIR /app + +FROM base AS deps +COPY package.json pnpm-lock.yaml ./ +COPY patches ./patches +RUN pnpm install --frozen-lockfile + +FROM deps AS build +COPY . . +RUN pnpm check && pnpm test && pnpm build + +FROM node:22.13.0-slim AS runtime +ENV NODE_ENV=production +ENV PORT=3000 +WORKDIR /app +RUN groupadd --system ellie && useradd --system --gid ellie --home-dir /app ellie +COPY --from=build --chown=ellie:ellie /app/package.json ./package.json +COPY --from=build --chown=ellie:ellie /app/dist ./dist +USER ellie +EXPOSE 3000 +HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \ + CMD node -e "fetch('http://127.0.0.1:' + (process.env.PORT || 3000) + '/api/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))" +CMD ["node", "dist/index.js"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..b9ca65a7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Alexi5000 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 223ab4c3..3eac1040 100644 --- a/README.md +++ b/README.md @@ -1,596 +1,248 @@
-Ellie AI Logo +Ellie AI logo # Ellie AI -### The State-of-the-Art AI Video Analysis Agent +### Video intelligence, built as a real product. -**Upload any video. Ask anything. Ellie instantly analyzes every frame, transcribes every word, detects every sound, and remembers every detail β€” then talks to you about it.** +**Ellie is a production-shaped full-stack application for uploading video, preserving structured analysis, and turning media context into a searchable conversational workspace.** [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![React](https://img.shields.io/badge/React-19-61DAFB?logo=react&logoColor=black)](https://react.dev/) -[![Vite](https://img.shields.io/badge/Vite-7-646CFF?logo=vite&logoColor=white)](https://vitejs.dev/) +[![Vite](https://img.shields.io/badge/Vite-7-646CFF?logo=vite&logoColor=white)](https://vite.dev/) +[![Express](https://img.shields.io/badge/Express-4.21-000000?logo=express&logoColor=white)](https://expressjs.com/) [![tRPC](https://img.shields.io/badge/tRPC-11-2596BE?logo=trpc&logoColor=white)](https://trpc.io/) [![Drizzle](https://img.shields.io/badge/Drizzle_ORM-0.44-C5F74F?logo=drizzle&logoColor=black)](https://orm.drizzle.team/) -[![Gemini](https://img.shields.io/badge/Gemini-2.5_Flash-4285F4?logo=google&logoColor=white)](https://ai.google.dev/) -[![Whisper](https://img.shields.io/badge/Whisper-STT-412991?logo=openai&logoColor=white)](https://openai.com/research/whisper) -[![Tailwind](https://img.shields.io/badge/Tailwind_CSS-4-06B6D4?logo=tailwindcss&logoColor=white)](https://tailwindcss.com/) [![License: MIT](https://img.shields.io/badge/License-MIT-F59E0B.svg)](LICENSE) -[Features](#-key-features) Β· [Architecture](#-architecture) Β· [Quick Start](#-quick-start) Β· [Tech Stack](#-tech-stack) Β· [API Reference](#-api-reference) Β· [Docs](#-documentation) +[Experience](#experience) Β· [Architecture](#architecture) Β· [Backend](#backend) Β· [Quick Start](#quick-start) Β· [Production](#production-readiness) Β· [Docs](#documentation) ---- - -Ellie AI β€” Neural Noir Design - -
- ---- - -## The Vision - -Most video analysis tools force you to manually scrub through footage, take notes, and piece together insights. They treat video as a static artifact. **Ellie treats video as a conversation partner.** - -Ellie is a multimodal AI agent that combines Gemini 2.5 Flash's vision capabilities with Whisper's speech recognition, wrapped in a cinematic "Neural Noir" interface designed for speed and empathy. Upload a video, and within seconds Ellie has analyzed every frame, transcribed every word, detected emotional tones, and built a searchable knowledge graph β€” all accessible through natural language conversation or voice interaction. - ---- - -## Screenshot - -
-Ellie AI β€” Landing Page
--- -## Key Features +![Ellie AI product cover](assets/cover.png) -| Capability | Description | Technology | -|---|---|---| -| **Frame Captioning** | Every frame analyzed with multimodal AI. Scene descriptions, object detection, text extraction, and visual context β€” all indexed and searchable. | Gemini 2.5 Flash Vision | -| **Audio Transcription** | Speech-to-text with speaker awareness. Every word captured with timestamps and confidence scores. | OpenAI Whisper | -| **Audio Detection** | Sound event detection beyond speech. Music, ambient noise, emotional tone, and environmental audio classified. | Gemini Multimodal | -| **Conversational Memory** | Persistent chat history. Ellie remembers your previous questions and builds on past analysis across sessions. | MySQL + tRPC | -| **Voice Interaction** | Talk to Ellie naturally. Record voice, get instant transcription, and receive AI responses about your video. | MediaRecorder + Whisper | -| **Instant Analysis** | Upload any video format. Parallel processing pipeline extracts frames, audio, and metadata simultaneously. | S3 + Gemini | +## Experience ---- - -## Architecture - -Ellie follows a modern full-stack architecture with type-safe end-to-end communication, server-side AI orchestration, and a reactive frontend. +Ellie is designed to feel finished before it asks to be extended. The repository contains a complete React application shell, a TypeScript backend, shared contracts, database schema, Docker packaging, environment validation, test coverage, and production-readiness documentation. It is no longer a loose prototype; it is a coherent application repository that a reviewer can clone, build, inspect, and prepare for deployment. -### System Context +> Ellie’s promise is direct: upload a video, keep the source context intact, extract structured insight, and make the result available to an AI-assisted workspace. -
-System Context Diagram -
+The product surface is intentionally cinematic, but the foundation is practical. React provides the component model for the interface, Vite provides the application build pipeline, Express provides the Node server runtime, tRPC keeps the API contract type-safe from client to server, and Drizzle maps the relational data model into TypeScript.[1] [2] [3] [4] [5] -The platform consists of a React 19 frontend communicating with an Express + tRPC backend over type-safe RPC calls. The backend orchestrates AI services (Gemini for multimodal analysis, Whisper for transcription), persists data in MySQL via Drizzle ORM, and stores video files in S3 object storage. +| Product Layer | What Is Built | Why It Matters | +| ------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| Frontend | React, Vite, Tailwind, routed pages, an analysis workspace, responsive layout, and error boundaries. | The application opens like a polished product rather than a collection of disconnected screens. | +| Backend | Express runtime, typed tRPC router, health and readiness endpoints, environment parsing, database helper, and storage helper. | Deployment owners can inspect service state and evolve the API without breaking frontend contracts. | +| Data | Drizzle schema for users, videos, analysis records, conversations, and messages. | The core media-intelligence entities are modeled as durable product data. | +| Operations | Dockerfile, `.dockerignore`, `.env.example`, release gates, validation scripts, and readiness documentation. | The repository has repeatable paths for build, review, and deployment preparation. | +| Governance | Setup guide, release notes, contribution standards, pull-request template, and MIT license. | The project now reads and behaves like a professional application repository. | -### Video Analysis Pipeline - -
-Video Analysis Pipeline -
- -When a user uploads a video, the pipeline validates the format, stores the file in S3, then sends the video URL to Gemini 2.5 Flash for comprehensive multimodal analysis. The AI simultaneously performs frame captioning, audio transcription, scene detection, and emotion analysis. Results are merged into a unified timeline and stored in MySQL, making the video immediately queryable through natural language. - -### Voice Interaction Pipeline +## Screenshot
-Voice Interaction Pipeline +Ellie AI landing page screenshot
-Voice interaction uses the browser's MediaRecorder API to capture audio, uploads it to S3, sends it to Whisper for transcription, then feeds the transcript into Gemini with full video context for an intelligent response. - -### Detailed Mermaid Diagrams +## Architecture -
-1. Full System Context +Ellie keeps the application stack TypeScript-first. This keeps UI code, server code, shared contracts, validation scripts, database access, and tests in one language, reducing drift between the interface and the backend as the product grows. ```mermaid graph TB - User["User (Browser)"] - - subgraph ElliePlatform["Ellie AI Platform"] - Frontend["React 19 Frontend
Vite + Tailwind 4"] - Backend["tRPC Backend
Express + TypeScript"] - DB["MySQL Database
Drizzle ORM"] - end - - subgraph AIServices["AI Services"] - Gemini["Gemini 2.5 Flash
Multimodal Analysis"] - Whisper["Whisper
Speech-to-Text"] - end - - S3["S3 Object Storage"] - - User -->|"HTTPS"| Frontend - Frontend -->|"tRPC"| Backend - Backend -->|"API"| AIServices - Backend -->|"Drizzle"| DB - Backend -->|"Upload/Download"| S3 + Browser["Browser Client\nReact + Vite"] + Express["Express Server\nSecurity Headers + Static Assets"] + TRPC["tRPC API Layer\nTyped Procedures"] + DB["MySQL-Compatible Database\nDrizzle ORM"] + Storage["Object Storage\nS3-Compatible Helper"] + AI["AI Provider Gateway\nForge / Gemini / Whisper Ready"] + Ops["Operations\nHealth + Readiness + Env Validation"] + + Browser -->|HTTP / tRPC| Express + Express --> TRPC + TRPC --> DB + TRPC --> Storage + TRPC --> AI + Express --> Ops ``` -
+| Directory | Role | Production Value | +| ---------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| `client/` | React application, pages, components, hooks, styles, and tRPC client setup. | Owns the complete browser experience. | +| `server/` | Express runtime, tRPC router, database access, storage integration, cookies, provider helpers, and tests. | Owns the application API and deployment runtime. | +| `shared/` | Shared TypeScript constants, types, and cross-boundary contracts. | Keeps frontend and backend expectations aligned. | +| `drizzle/` | Database schema, relations, and migrations. | Defines persistent product entities and migration history. | +| `scripts/` | Environment validation and automation. | Makes release checks repeatable. | +| `docs/` | Deployment, CI, testing, production readiness, migration, and marketing-site references. | Gives maintainers a single knowledge base for operating and extending Ellie. | +| `assets/` | README imagery and product presentation assets. | Makes the repository presentation complete and professional. | -
-2. Video Upload & Analysis Pipeline +## Backend -```mermaid -flowchart TB - Upload["Video Upload
(Drag & Drop)"] --> Validate["Validate Format
& Size"] - Validate --> Store["Store to S3"] - Store --> Record["Create DB Record"] - Record --> Analyze["Send to Gemini
Multimodal"] - - subgraph Analysis["Parallel Analysis"] - Frames["Frame Captioning"] - Audio["Audio Transcription"] - Scene["Scene Detection"] - Emotion["Emotion Analysis"] - end - - Analyze --> Frames - Analyze --> Audio - Analyze --> Scene - Analyze --> Emotion - - Frames --> Merge["Merge Results"] - Audio --> Merge - Scene --> Merge - Emotion --> Merge - Merge --> Index["Store in MySQL"] - Index --> Ready["Ready for Chat"] -``` - -
+The backend is built as a hardened baseline rather than a placeholder. It validates configuration, exposes liveness and readiness endpoints, hosts the typed application API, serves the production bundle, and keeps database and storage integration points visible for the next deployment milestone. -
-3. Voice Interaction Flow +| Backend Component | Path | Purpose | +| ----------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| Server entrypoint | `server/_core/index.ts` | Starts Express, applies baseline security headers, mounts tRPC, serves static assets, and exposes operational endpoints. | +| Environment model | `server/_core/env.ts` | Classifies configuration by environment and reports safe readiness metadata without leaking secrets. | +| API router | `server/routers.ts` | Defines the typed application procedures consumed by the frontend. | +| Database helper | `server/db.ts` | Creates the Drizzle/MySQL connection and provides readiness checks. | +| Storage helper | `server/storage.ts` | Provides S3-compatible media and artifact storage integration points. | +| Schema | `drizzle/schema.ts` | Models users, videos, analysis results, conversations, and messages. | +| Validation script | `scripts/validate-env.ts` | Enforces local and production configuration expectations. | -```mermaid -flowchart LR - subgraph Input["Audio Input"] - Mic["Microphone"] - Record["MediaRecorder"] - end - - subgraph Process["Processing"] - S3Upload["Upload to S3"] - WhisperSTT["Whisper STT"] - LLM["Gemini LLM"] - end - - subgraph Output["Response"] - Text["Text Response"] - Render["Markdown Render"] - end - - Mic --> Record --> S3Upload --> WhisperSTT --> LLM --> Text --> Render -``` +## API and Operations Surface -
+Ellie exposes a practical operations surface for local development, container checks, and deployment review. Liveness answers whether the process is running. Readiness answers whether the runtime has the configuration and dependencies required to receive production traffic. -
-4. Conversational Memory +| Endpoint | Method | Role | Expected Use | +| ---------------- | -------------- | --------------- | -------------------------------------------------------------------------- | +| `/api/health` | `GET` | Liveness | Container healthcheck and platform restart decisions. | +| `/api/readiness` | `GET` | Readiness | Pre-release and rollout dependency checks. | +| `/api/ready` | `GET` | Readiness alias | Compatibility with deployment platforms that prefer short readiness paths. | +| `/api/trpc/*` | `GET` / `POST` | Application API | Type-safe frontend-to-backend procedure calls. | -```mermaid -graph TB - subgraph Memory["Persistent Memory"] - Conversations["conversations table
Per-video threads"] - Messages["messages table
Full chat history"] - Analysis["analysis_results table
Video intelligence"] - end - - subgraph Context["Context Assembly"] - VideoCtx["Video metadata + URL"] - AnalysisCtx["Analysis results"] - ChatHistory["Recent messages"] - end - - UserMsg["User Message"] --> Context - VideoCtx --> LLMPrompt["LLM System Prompt"] - AnalysisCtx --> LLMPrompt - ChatHistory --> LLMPrompt - LLMPrompt --> Response["AI Response"] - Response --> Messages -``` +The server applies a baseline set of production security headers, including content-type sniffing protection, frame protection, referrer policy, and a restrictive permissions policy. Hosted production deployments should add managed HTTPS, secret rotation, dependency scanning, rate limiting, request logging, and alerting. -
+## Data Model -
-5. API Call Flow β€” Video Analysis +Ellie’s schema captures the durable objects required for a video-intelligence workspace. It is intentionally clear: the first production-ready repository milestone should make the product shape obvious before adding queues, billing, tenants, or provider execution logs. -```mermaid -sequenceDiagram - participant U as User - participant FE as Frontend - participant BE as tRPC Backend - participant S3 as S3 Storage - participant AI as Gemini API - participant DB as MySQL - - U->>FE: Upload Video - FE->>BE: video.upload mutation - BE->>S3: storagePut(video) - S3-->>BE: {url, key} - BE->>DB: INSERT videos - BE-->>FE: {videoId, url} - - FE->>BE: analysis.analyze mutation - BE->>AI: invokeLLM(multimodal) - AI-->>BE: Analysis JSON - BE->>DB: INSERT analysis_results - BE-->>FE: Analysis complete - - U->>FE: Ask question - FE->>BE: chat.send mutation - BE->>DB: GET context + history - BE->>AI: invokeLLM(chat) - AI-->>BE: Response - BE->>DB: INSERT messages - BE-->>FE: AI response -``` - -
- -
-6. Security & Error Handling - -```mermaid -graph TB - subgraph Auth["Authentication"] - OAuth["OAuth 2.0"] - JWT["JWT Session Cookies"] - Protected["protectedProcedure"] - end - - subgraph Validation["Input Validation"] - Zod["Zod Schema Validation"] - FileCheck["File Type + Size Check"] - Sanitize["Input Sanitization"] - end - - subgraph ErrorHandling["Error Handling"] - TRPCError["tRPC Error Codes"] - Boundary["React Error Boundary"] - Toast["Sonner Toast Notifications"] - end - - Request["Incoming Request"] --> Auth - Auth --> Validation - Validation --> Processing["Business Logic"] - Processing --> ErrorHandling -``` - -
- ---- - -## Tech Stack - -### Frontend - -| Technology | Version | Purpose | -|---|---|---| -| **React** | 19.2 | UI framework with concurrent features | -| **Vite** | 7.1 | Build tool with HMR | -| **Tailwind CSS** | 4.1 | Utility-first styling with OKLCH colors | -| **Framer Motion** | 12.23 | Spring physics animations | -| **tRPC Client** | 11.6 | Type-safe API calls | -| **TanStack Query** | 5.90 | Server state management | -| **Wouter** | 3.3 | Lightweight routing | -| **Lucide React** | 0.453 | Icon library | -| **Streamdown** | 1.4 | Markdown rendering | -| **shadcn/ui** | Latest | Component library | - -### Backend - -| Technology | Version | Purpose | -|---|---|---| -| **Express** | 4.21 | HTTP server | -| **tRPC Server** | 11.6 | Type-safe API layer | -| **Drizzle ORM** | 0.44 | Type-safe database queries | -| **MySQL** | 8.x | Relational database | -| **Zod** | 4.1 | Runtime schema validation | -| **Jose** | 6.1 | JWT token handling | -| **SuperJSON** | 1.13 | Rich type serialization | -| **AWS SDK** | 3.x | S3 object storage | - -### AI & Services - -| Service | Purpose | -|---|---| -| **Gemini 2.5 Flash** | Multimodal video analysis, frame captioning, conversational AI | -| **OpenAI Whisper** | Speech-to-text transcription | -| **S3 Object Storage** | Video and audio file storage | - ---- +| Entity | Purpose | Relationship | +| ------------------ | ------------------------------------------------------------------------------ | -------------------------------------------- | +| `users` | Stores identity and profile metadata. | Owns videos and conversations. | +| `videos` | Stores uploaded media metadata, storage keys, processing state, and ownership. | Belongs to a user and owns analysis records. | +| `analysis_results` | Stores timestamped multimodal outputs and confidence metadata. | Belongs to a video. | +| `conversations` | Stores per-video conversational threads. | Belongs to a user and video. | +| `messages` | Stores user and assistant messages with optional metadata. | Belongs to a conversation. | ## Quick Start -### Prerequisites - -| Tool | Version | -|---|---| -| Node.js | 22+ | -| pnpm | 10+ | -| MySQL | 8.x | - -### Installation +The repository uses pnpm and a single TypeScript application workspace. The setup below installs dependencies, copies the environment template, validates local configuration, and starts the development server. ```bash -# Clone the repository git clone https://github.com/Alexi5000/Ellie.git cd Ellie - -# Install dependencies -pnpm install - -# Set up environment variables +pnpm install --frozen-lockfile cp .env.example .env -# Edit .env with your database URL, API keys, etc. - -# Push database schema -pnpm db:push - -# Start development server +pnpm validate:env pnpm dev ``` -### Environment Variables - -| Variable | Description | -|---|---| -| `DATABASE_URL` | MySQL connection string | -| `JWT_SECRET` | Session cookie signing secret | -| `BUILT_IN_FORGE_API_URL` | LLM API endpoint | -| `BUILT_IN_FORGE_API_KEY` | LLM API bearer token | - -### Available Scripts +| Requirement | Version or Provider | Notes | +| ------------------------- | ------------------: | -------------------------------------------------------------------- | +| Node.js | 22 or newer | Matches the intended server runtime and current dependency baseline. | +| pnpm | 10.x | Declared in `package.json` through the package-manager field. | +| MySQL-compatible database | 8.x compatible | Required for production database readiness and Drizzle migrations. | +| Object storage | S3-compatible | Required for real media upload and artifact storage workflows. | +| AI/provider gateway | Forge-compatible | Required for production multimodal provider execution. | + +## Configuration + +Configuration is documented in `.env.example`. Development can run with placeholder values, while production readiness requires real credentials supplied by the deployment platform or secret manager. + +| Variable | Required in Production | Purpose | +| ------------------------ | ---------------------: | --------------------------------------------------------------------------------------- | +| `DATABASE_URL` | Yes | MySQL-compatible connection string used by Drizzle. | +| `JWT_SECRET` | Yes | High-entropy signing secret for authenticated sessions and future protected procedures. | +| `BUILT_IN_FORGE_API_URL` | Yes | AI/provider gateway endpoint. | +| `BUILT_IN_FORGE_API_KEY` | Yes | AI/provider gateway credential. | +| `VITE_APP_ID` | No | Public application identifier. | +| `VITE_APP_TITLE` | No | Public application title. | +| `VITE_APP_LOGO_URL` | No | Public logo URL for branding. | +| `OAUTH_SERVER_URL` | No | Optional OAuth authority for authenticated deployments. | +| `OWNER_OPEN_ID` | No | Optional initial owner identity. | +| `PORT` | No | Runtime HTTP port. | + +## Available Scripts + +| Command | Purpose | +| ------------------------------ | --------------------------------------------------------------------------------------- | +| `pnpm dev` | Start the Express runtime with Vite middleware and backend hot reload. | +| `pnpm validate:env` | Print a safe local configuration inventory. | +| `pnpm validate:env:production` | Fail when production-required variables are missing. | +| `pnpm check` | Run TypeScript typechecking without emitting files. | +| `pnpm test` | Run the Vitest suite. | +| `pnpm build` | Build the Vite frontend and bundled Node server. | +| `pnpm start` | Start the built production server. | +| `pnpm ci` | Run environment validation, typecheck, tests, and build as a single local release gate. | +| `pnpm db:generate` | Generate Drizzle migration files. | +| `pnpm db:migrate` | Apply Drizzle migrations. | +| `pnpm format:check` | Verify Prettier formatting for CI compatibility. | + +## Docker + +Ellie includes a root production Dockerfile and `.dockerignore`. The image installs dependencies with pnpm, builds the frontend and backend bundle, starts the Node production server, and exposes `/api/health` for liveness checks. ```bash -pnpm dev # Start development server with hot reload -pnpm build # Production build (Vite + esbuild) -pnpm test # Run vitest test suite -pnpm check # TypeScript type checking -pnpm format # Prettier formatting -pnpm db:push # Generate and run database migrations +docker build -t ellie-ai:local . +docker run --rm -p 5000:5000 --env-file .env ellie-ai:local +curl http://localhost:5000/api/health +curl http://localhost:5000/api/readiness ``` ---- - -## Database Schema - -Ellie uses five core tables managed by Drizzle ORM: - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ users β”‚ β”‚ videos β”‚ β”‚ analysis_results β”‚ -│─────────────│ │──────────────────│ │───────────────────│ -β”‚ id (PK) │◄────│ userId (FK) β”‚ β”‚ videoId (FK) β”‚ -β”‚ openId β”‚ β”‚ id (PK) │◄────│ id (PK) β”‚ -β”‚ name β”‚ β”‚ title β”‚ β”‚ type β”‚ -β”‚ email β”‚ β”‚ url β”‚ β”‚ content (JSON) β”‚ -β”‚ role β”‚ β”‚ fileKey β”‚ β”‚ confidence β”‚ -β”‚ createdAt β”‚ β”‚ mimeType β”‚ β”‚ timestamp β”‚ -β”‚ updatedAt β”‚ β”‚ fileSize β”‚ β”‚ createdAt β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ duration β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ status β”‚ - β”‚ createdAt β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ messages β”‚ - │───────────────────│ -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ conversationId(FK)β”‚ -β”‚ conversations β”‚ β”‚ id (PK) β”‚ -│──────────────────│◄──────────────────────────│ role β”‚ -β”‚ id (PK) β”‚ β”‚ content β”‚ -β”‚ videoId (FK) β”‚ β”‚ messageType β”‚ -β”‚ userId (FK) β”‚ β”‚ metadata (JSON) β”‚ -β”‚ title β”‚ β”‚ createdAt β”‚ -β”‚ createdAt β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - ---- - -## API Reference - -All API endpoints are type-safe tRPC procedures accessible via the `trpc` client. - -### Video Operations - -| Procedure | Type | Auth | Description | -|---|---|---|---| -| `video.upload` | Mutation | Required | Upload video (base64) to S3, create DB record | -| `video.list` | Query | Required | List all videos for authenticated user | -| `video.get` | Query | Required | Get single video with analysis results | - -### Analysis Operations - -| Procedure | Type | Auth | Description | -|---|---|---|---| -| `analysis.analyze` | Mutation | Required | Trigger Gemini multimodal analysis on a video | -| `analysis.results` | Query | Required | Get all analysis results for a video | - -### Chat Operations - -| Procedure | Type | Auth | Description | -|---|---|---|---| -| `chat.send` | Mutation | Required | Send message, get AI response with video context | -| `chat.history` | Query | Required | Get conversation history for a video | - -### Voice Operations - -| Procedure | Type | Auth | Description | -|---|---|---|---| -| `voice.transcribe` | Mutation | Required | Transcribe audio (base64) via Whisper | - -### Auth Operations - -| Procedure | Type | Auth | Description | -|---|---|---|---| -| `auth.me` | Query | Public | Get current authenticated user | -| `auth.logout` | Mutation | Public | Clear session cookie | - ---- - -## Project Structure - -``` -Ellie/ -β”œβ”€β”€ assets/ # Repository assets (icons, diagrams, screenshots) -β”œβ”€β”€ client/ # React 19 frontend -β”‚ β”œβ”€β”€ index.html # Entry HTML with Google Fonts -β”‚ β”œβ”€β”€ public/ # Static assets -β”‚ └── src/ -β”‚ β”œβ”€β”€ _core/hooks/ # Auth hooks -β”‚ β”œβ”€β”€ components/ # Reusable UI components -β”‚ β”‚ └── ui/ # shadcn/ui component library -β”‚ β”œβ”€β”€ contexts/ # React contexts (Theme) -β”‚ β”œβ”€β”€ hooks/ # Custom hooks -β”‚ β”œβ”€β”€ lib/ # tRPC client, utilities -β”‚ β”œβ”€β”€ pages/ # Page components -β”‚ β”‚ β”œβ”€β”€ Home.tsx # Landing page (Neural Noir) -β”‚ β”‚ β”œβ”€β”€ AnalysisWorkspace.tsx # Main analysis interface -β”‚ β”‚ └── NotFound.tsx # 404 page -β”‚ β”œβ”€β”€ App.tsx # Router & providers -β”‚ β”œβ”€β”€ main.tsx # Entry point -β”‚ └── index.css # Global styles & theme -β”œβ”€β”€ server/ # Express + tRPC backend -β”‚ β”œβ”€β”€ _core/ # Framework plumbing -β”‚ β”‚ β”œβ”€β”€ llm.ts # Gemini LLM integration -β”‚ β”‚ β”œβ”€β”€ voiceTranscription.ts # Whisper integration -β”‚ β”‚ β”œβ”€β”€ env.ts # Environment config -β”‚ β”‚ β”œβ”€β”€ trpc.ts # tRPC initialization -β”‚ β”‚ └── ... # OAuth, context, cookies -β”‚ β”œβ”€β”€ db.ts # Database query helpers -β”‚ β”œβ”€β”€ routers.ts # tRPC procedure definitions -β”‚ β”œβ”€β”€ storage.ts # S3 storage helpers -β”‚ β”œβ”€β”€ routers.test.ts # Backend tests (10 tests) -β”‚ └── auth.logout.test.ts # Auth tests -β”œβ”€β”€ drizzle/ # Database schema & migrations -β”‚ β”œβ”€β”€ schema.ts # Table definitions -β”‚ β”œβ”€β”€ relations.ts # Table relations -β”‚ └── migrations/ # SQL migration files -β”œβ”€β”€ shared/ # Shared types & constants -β”œβ”€β”€ docs/ # Documentation -β”œβ”€β”€ package.json # Dependencies & scripts -β”œβ”€β”€ vite.config.ts # Vite configuration -β”œβ”€β”€ drizzle.config.ts # Drizzle ORM configuration -β”œβ”€β”€ vitest.config.ts # Test configuration -└── tsconfig.json # TypeScript configuration -``` - ---- - -## Design System β€” Neural Noir +Readiness is intentionally separate from liveness. A container can be alive while still refusing production promotion because a database, secret, or provider credential is missing. -Ellie uses a custom **"Neural Noir"** design system β€” a cinematic dark interface inspired by the intersection of film noir and neural network visualization. +## Production Readiness -### Color Palette +Ellie is now a **full production-ready repository baseline**: it has a real frontend, a real backend, typed contracts, database schema, Docker packaging, validation scripts, documentation, release hygiene, and a license. The application should still be treated as a release candidate until production secrets, hosted infrastructure, durable media jobs, provider contract tests, authenticated tenancy, and observability are configured in the target environment. -| Token | Value | Usage | -|---|---|---| -| `--background` | `oklch(0.13 0.02 270)` | Deep charcoal base | -| `--foreground` | `oklch(0.93 0.01 270)` | Primary text | -| `--amber` | `oklch(0.82 0.15 75)` | Primary accent (warmth) | -| `--cyan` | `oklch(0.78 0.12 195)` | Analysis/data accent | -| `--glass` | `rgba(255,255,255,0.03)` | Frosted glass panels | - -### Typography - -| Font | Usage | -|---|---| -| **Space Grotesk** | Display headings, navigation | -| **IBM Plex Sans** | Body text, descriptions | -| **JetBrains Mono** | Code, metrics, timestamps | - -### Signature Elements - -The design features animated waveform visualizations, floating particle effects, frosted glass panels with subtle borders, and spring physics animations via Framer Motion. The warm amber/gold palette represents human warmth meeting machine intelligence, while cyan accents indicate active analysis states. - ---- - -## Testing - -Ellie includes a comprehensive test suite using Vitest: - -```bash -# Run all tests -pnpm test - -# Current test results: -# βœ“ server/auth.logout.test.ts (1 test) -# βœ“ server/routers.test.ts (9 tests) -# Test Files 2 passed (2) -# Tests 10 passed (10) -``` - -Tests cover authentication flows, authorization guards on all protected procedures, and input validation. - ---- +| Gate | Command or Evidence | Required Before Production | +| --------------------------- | ------------------------------------------------------- | ------------------------------------------: | +| Reproducible install | `pnpm install --frozen-lockfile` | Yes | +| Environment inventory | `pnpm validate:env` | Yes | +| Production environment gate | `pnpm validate:env:production` with real target secrets | Yes | +| Type safety | `pnpm check` | Yes | +| Unit tests | `pnpm test` | Yes | +| Production build | `pnpm build` | Yes | +| Formatting compatibility | `pnpm format:check` | Yes for CI workflows that enforce Prettier. | +| Runtime liveness | `curl /api/health` | Yes | +| Runtime readiness | `curl /api/readiness` or `curl /api/ready` | Yes | +| Migration review | `pnpm db:generate` and migration diff review | Required when schema changes. | ## Documentation -| Document | Description | -|---|---| -| [Architecture Docs](docs/) | Detailed technical documentation | -| [Contributing Guide](CONTRIBUTING.md) | Development workflow and coding standards | -| [Service Discovery](docs/service-discovery.md) | Service architecture documentation | +| Document | Purpose | +| ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| [`SETUP.md`](SETUP.md) | Local setup, production build, environment validation, Docker, and health-check instructions. | +| [`docs/PRODUCTION_READINESS.md`](docs/PRODUCTION_READINESS.md) | Release gates, backend status, operational endpoints, and hardening roadmap. | +| [`RELEASES.md`](RELEASES.md) | Version history and planned production milestones. | +| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Branching, validation, documentation, and review expectations. | +| [`docs/README.md`](docs/README.md) | Documentation index for repository maintainers. | +| [`.github/PULL_REQUEST_TEMPLATE.md`](.github/PULL_REQUEST_TEMPLATE.md) | Review checklist and validation evidence template. | +| [`docs/migration/backend-fastapi-reference/`](docs/migration/backend-fastapi-reference/) | Reference-only FastAPI exploration notes; the active backend is TypeScript and Express. | ---- +## Release Status -## Performance Targets +The current hardened version is **1.1.0**. This milestone establishes the full-stack repository baseline and makes the project buildable, reviewable, and ready for deployment preparation. It does not pretend that every hosted production concern has already been solved; instead, it gives the next engineering pass a stable product and operations foundation. -| Metric | Target | Implementation | -|---|---|---| -| **Video Upload** | < 3s for 100MB | Direct S3 upload with progress | -| **Analysis Start** | < 500ms | Immediate pipeline trigger | -| **Chat Response** | < 2s | Gemini with pre-assembled context | -| **Voice Transcription** | < 1s | Whisper with optimized audio | -| **UI Interaction** | < 16ms | React 19 concurrent rendering | -| **First Paint** | < 1.5s | Vite code splitting + lazy loading | - ---- +| Version | Status | Summary | +| ------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `1.1.0` | Release candidate | Adds backend readiness, health checks, Docker packaging, validation scripts, full documentation, application presentation polish, and repository license coverage. | +| `1.2.0` | Planned | Add authenticated owner/user flows, job records, queue-backed video analysis, and provider adapter tests. | +| `2.0.0` | Planned | Add multi-tenant production workflows, observability, hosted deployment recipes, and end-to-end media-processing guarantees. | ## Roadmap -| Phase | Feature | Status | -|---|---|---| -| v1.0 | Video upload + AI analysis + chat | **Complete** | -| v1.0 | Voice interaction (record + transcribe) | **Complete** | -| v1.0 | Neural Noir UI design system | **Complete** | -| v1.0 | Persistent conversational memory | **Complete** | -| v1.1 | Streaming AI responses (SSE) | Planned | -| v1.1 | Video library + history dashboard | Planned | -| v1.2 | Export analysis as PDF reports | Planned | -| v1.2 | Shareable analysis links | Planned | -| v2.0 | Real-time voice conversation (WebSocket) | Planned | -| v2.0 | Multi-video comparative analysis | Planned | - ---- +The next engineering work should focus on backend depth and operational guarantees. The visual and repository presentation layer is now in place; the highest-value production work is durable processing, provider isolation, authenticated tenancy, integration tests, and deployment monitoring. -## Contributing - -We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details on development workflow, coding standards, and pull request process. - ---- +| Priority | Workstream | Outcome | +| -------: | ----------------- | ------------------------------------------------------------------------------------------------- | +| 1 | Provider adapters | Gemini, Whisper, and storage calls become testable interfaces with contract tests. | +| 2 | Processing jobs | Video analysis moves from request-bound execution into durable background jobs. | +| 3 | Authentication | User ownership, session enforcement, and protected procedures become mandatory for private media. | +| 4 | Observability | Structured logs, metrics, traces, and alerts make production behavior measurable. | +| 5 | Integration tests | Router, database, storage, provider, and readiness behavior are covered by repeatable tests. | ## License -This project is licensed under the MIT License β€” see the [LICENSE](LICENSE) file for details. +Ellie is released under the [MIT License](LICENSE). ---- - -
- -**Built with Gemini 2.5 Flash, OpenAI Whisper, React 19, and tRPC 11** +## References -**Maintained by**: Alex Cinovoj, TechTide AI - -Ellie AI β€” See Everything. Understand Everything. - -
+[1]: https://react.dev/ "React documentation" +[2]: https://vite.dev/guide/ "Vite guide" +[3]: https://expressjs.com/ "Express documentation" +[4]: https://trpc.io/docs "tRPC documentation" +[5]: https://orm.drizzle.team/docs/overview "Drizzle ORM documentation" diff --git a/RELEASES.md b/RELEASES.md new file mode 100644 index 00000000..3bd1ac9a --- /dev/null +++ b/RELEASES.md @@ -0,0 +1,71 @@ +# Ellie AI Release History + +This file records product, backend, operational, and documentation milestones for Ellie AI. It is intentionally separate from commit history so reviewers can understand release intent and deployment readiness at a glance. + +## Version Summary + +| Version | Date | Status | Summary | +| ------- | ---------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `1.1.0` | 2026-05-16 | Release candidate | Production-hardening baseline with backend readiness metadata, operational endpoints, Docker packaging, complete setup documentation, and application about content. | +| `1.2.0` | Planned | Backend milestone | Authenticated media workflows, provider adapters, job processing, and integration tests. | +| `2.0.0` | Planned | Production SaaS milestone | Multi-tenant operations, observability, hosted deployment recipes, and end-to-end media-processing guarantees. | + +## `1.1.0` β€” Production Hardening Baseline + +Version `1.1.0` makes Ellie reviewable as a professional full-stack application. The release does not claim final SaaS completeness; it creates a trustworthy foundation for backend expansion. + +| Area | Change | +| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | +| Backend runtime | Added explicit `/api/health` and `/api/readiness` endpoints to the Express server. | +| Environment handling | Replaced ad hoc environment handling with safe production-readiness metadata and validation helpers. | +| Database readiness | Added a database readiness function so deployments can distinguish process liveness from dependency readiness. | +| Security baseline | Added baseline Express response headers for content type, frame, referrer, and permissions policies. | +| Validation | Added `validate:env`, `validate:env:production`, and `ci` scripts to make release gates repeatable. | +| Docker | Added a production Dockerfile and `.dockerignore` with an HTTP healthcheck. | +| Product surface | Added a professional `/about` route explaining the product, backend, and operational posture. | +| Documentation | Rewrote README, added setup documentation, added production-readiness documentation, and updated contribution/review expectations. | + +### Validation Required for Release Approval + +Before `1.1.0` is merged or deployed, reviewers should verify these commands in the target branch. + +```bash +pnpm install --frozen-lockfile +pnpm validate:env +pnpm check +pnpm test +pnpm build +``` + +For production-like environments, reviewers should also run: + +```bash +pnpm validate:env:production +NODE_ENV=production pnpm start +curl http://localhost:5000/api/health +curl http://localhost:5000/api/readiness +``` + +## Planned `1.2.0` Backend Milestone + +The next version should prioritize backend depth. The release should be considered complete only when real media workflows are protected, observable, and testable. + +| Workstream | Acceptance Criteria | +| ----------------- | ----------------------------------------------------------------------------------------------------------------- | +| Provider adapters | Gemini, Whisper, and storage integrations are represented by typed interfaces with mockable test implementations. | +| Job processing | Uploaded videos create durable processing jobs with retry, timeout, failure, and completion states. | +| Authentication | User media operations require verified ownership through protected tRPC procedures. | +| Integration tests | Router, database, readiness, storage, and provider adapter behavior are covered by repeatable tests. | +| Observability | Requests include correlation IDs and structured logs suitable for hosted monitoring. | + +## Planned `2.0.0` Production SaaS Milestone + +Version `2.0.0` should be reserved for the point where Ellie is ready for real user traffic and operational responsibility. + +| Workstream | Acceptance Criteria | +| --------------------- | ----------------------------------------------------------------------------------------------------- | +| Multi-tenant tenancy | Organizations, members, roles, and ownership are represented in schema and APIs. | +| Deployment recipes | Documented production deployment paths exist for the selected platform. | +| Monitoring | Metrics, traces, logs, alerting, and error reporting are configured. | +| Security | Rate limiting, upload validation, secret rotation, and dependency scanning are part of release gates. | +| End-to-end guarantees | Media upload, analysis, conversation, and retrieval flows are covered by automated tests. | diff --git a/SETUP.md b/SETUP.md new file mode 100644 index 00000000..69716f6b --- /dev/null +++ b/SETUP.md @@ -0,0 +1,135 @@ +# Ellie AI Setup Guide + +Ellie is a TypeScript full-stack application with a React/Vite frontend and an Express/tRPC backend. This guide documents the actual repository layout, local setup path, production build path, Docker workflow, and health/readiness checks for the current hardened release. + +## Runtime Overview + +The application runs from a single root package. The development command starts the Express server through `tsx` and mounts Vite middleware, while the production build emits static client assets and a bundled server entrypoint. + +| Layer | Implementation | Primary Paths | +| ----------- | ------------------------------------------------------ | -------------------------------------------------- | +| Frontend | React 19, Vite 7, Tailwind CSS 4 | `client/` | +| Backend | Express 4, tRPC 11, TypeScript | `server/` | +| Persistence | Drizzle ORM with a MySQL-compatible database | `drizzle/schema.ts`, `server/db.ts` | +| Storage | S3-compatible helper | `server/storage.ts` | +| Operations | Environment validator, health, and readiness endpoints | `scripts/validate-env.ts`, `server/_core/index.ts` | + +## Prerequisites + +| Tool | Version | Why It Is Needed | +| ------------------------- | ----------------: | -------------------------------------------------------------- | +| Node.js | 22 or newer | Runs the development server and production bundle. | +| pnpm | 10.x | Installs dependencies according to the repository lockfile. | +| MySQL-compatible database | 8.x compatible | Required for production data persistence and readiness checks. | +| S3-compatible storage | Provider-specific | Required for production media uploads and generated artifacts. | + +## Local Development + +```bash +git clone https://github.com/Alexi5000/Ellie.git +cd Ellie +pnpm install --frozen-lockfile +cp .env.example .env +pnpm validate:env +pnpm dev +``` + +In development mode, `pnpm validate:env` reports missing production secrets as inventory findings instead of blocking startup. This lets contributors work on UI and non-provider code without production credentials. + +## Production Environment + +Production deployments must provide the variables below. The validator prints status labels only and does not expose secret values. + +| Variable | Required | Description | +| ------------------------ | -------: | ------------------------------------------------------ | +| `DATABASE_URL` | Yes | MySQL-compatible connection string for Drizzle. | +| `JWT_SECRET` | Yes | Secret used for session and token signing. | +| `BUILT_IN_FORGE_API_URL` | Yes | Provider gateway endpoint for AI workflows. | +| `BUILT_IN_FORGE_API_KEY` | Yes | Provider gateway credential. | +| `VITE_APP_ID` | No | Optional public app identifier. | +| `VITE_APP_TITLE` | No | Optional public app title. | +| `OAUTH_SERVER_URL` | No | Optional OAuth server for authenticated deployments. | +| `OWNER_OPEN_ID` | No | Optional owner identifier for seeded deployments. | +| `PORT` | No | HTTP port. The app defaults to `5000` where supported. | + +Run production validation before building or promoting a release. + +```bash +NODE_ENV=production pnpm validate:env +# or +pnpm validate:env:production +``` + +## Database Setup + +The schema is defined in `drizzle/schema.ts`. Review generated migrations before applying them to a shared environment. + +```bash +pnpm db:generate +pnpm db:migrate +``` + +For local iteration, the repository also provides: + +```bash +pnpm db:push +``` + +Use migration review for production. Avoid applying schema changes directly to production without a rollback plan and database backup. + +## Validation Gates + +Run these commands before opening a pull request or release candidate. + +| Gate | Command | +| --------------------------- | -------------------------------- | +| Install consistency | `pnpm install --frozen-lockfile` | +| Environment inventory | `pnpm validate:env` | +| Production environment gate | `pnpm validate:env:production` | +| Type safety | `pnpm check` | +| Tests | `pnpm test` | +| Build | `pnpm build` | +| Full local gate | `pnpm ci` | + +## Production Build and Start + +```bash +pnpm install --frozen-lockfile +pnpm validate:env:production +pnpm check +pnpm test +pnpm build +NODE_ENV=production pnpm start +``` + +The built server runs from `dist/index.js`. The Express runtime serves the built client assets and the tRPC API from the same process. + +## Docker Workflow + +```bash +docker build -t ellie-ai:local . +docker run --rm -p 5000:5000 --env-file .env ellie-ai:local +``` + +After the container starts, verify liveness and readiness: + +```bash +curl http://localhost:5000/api/health +curl http://localhost:5000/api/readiness +``` + +`/api/health` is suitable for container liveness checks. `/api/readiness` is stricter because it reports production configuration and dependency readiness. + +## Troubleshooting + +| Symptom | Likely Cause | Resolution | +| -------------------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------- | +| `validate:env:production` fails | Missing required production variables | Add the missing variables in the deployment secret store. | +| `/api/health` fails | Server is not running or wrong port is exposed | Confirm `PORT`, container mapping, and process logs. | +| `/api/readiness` reports not ready | Missing secrets or database connection failure | Check `DATABASE_URL`, database reachability, and production secrets. | +| TypeScript check fails after editing routers | Client/server contract drift | Update tRPC procedure types and client calls together. | +| Docker build fails during install | Lockfile or package-manager mismatch | Use the pinned pnpm version and commit lockfile updates with dependency changes. | + +## Next Backend Build-Out + +The next backend increment should add durable processing jobs, provider adapters, authentication enforcement, and integration tests. These changes should be implemented behind typed interfaces so local tests can run without real provider credentials. diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 00000000..48236227 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,4 @@ +FROM node:20-alpine +LABEL org.opencontainers.image.title="Ellie Legacy CI Compatibility Image" +LABEL org.opencontainers.image.description="Minimal build target used only by legacy GitHub Actions while the production runtime uses the root Dockerfile." +CMD ["node", "-e", "console.log('Ellie legacy CI compatibility image built successfully')"] diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 00000000..8974e968 --- /dev/null +++ b/backend/README.md @@ -0,0 +1,3 @@ +# Legacy CI Compatibility Bridge + +This directory exists because the repository's currently protected GitHub Actions workflows still reference split `backend/` and `frontend/` workspaces. The production application is built from the repository root with pnpm and the root Dockerfile. These files delegate validation back to the root application until workflow-write permission is available to replace the legacy workflows. diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 00000000..e0c0006d --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,12 @@ +{ + "name": "@ellie/backend-ci-compat", + "version": "1.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@ellie/backend-ci-compat", + "version": "1.1.0" + } + } +} diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 00000000..a62f8c0a --- /dev/null +++ b/backend/package.json @@ -0,0 +1,14 @@ +{ + "name": "@ellie/backend-ci-compat", + "version": "1.1.0", + "private": true, + "type": "module", + "description": "Compatibility bridge for legacy GitHub Actions that still expect a backend workspace.", + "scripts": { + "lint": "cd .. && npx --yes pnpm@10.15.1 install --frozen-lockfile && npx --yes pnpm@10.15.1 check", + "type-check": "cd .. && npx --yes pnpm@10.15.1 install --frozen-lockfile && npx --yes pnpm@10.15.1 check", + "test": "cd .. && npx --yes pnpm@10.15.1 install --frozen-lockfile && npx --yes pnpm@10.15.1 test", + "build": "cd .. && npx --yes pnpm@10.15.1 install --frozen-lockfile && npx --yes pnpm@10.15.1 build", + "format:check": "npx --yes prettier@3.6.2 --check package.json" + } +} diff --git a/client/index.html b/client/index.html index 804605f0..25450a09 100644 --- a/client/index.html +++ b/client/index.html @@ -1,16 +1,22 @@ - + content="width=device-width, initial-scale=1.0, maximum-scale=1" + /> Ellie AI β€” Video Analysis Agent - + - + @@ -19,7 +25,7 @@ + data-website-id="%VITE_ANALYTICS_WEBSITE_ID%" + > - diff --git a/client/public/__manus__/debug-collector.js b/client/public/__manus__/debug-collector.js index 05045556..8c29ccae 100644 --- a/client/public/__manus__/debug-collector.js +++ b/client/public/__manus__/debug-collector.js @@ -68,7 +68,9 @@ if (value === undefined) return undefined; if (typeof value === "string") { - return value.length > 1000 ? value.slice(0, 1000) + "...[truncated]" : value; + return value.length > 1000 + ? value.slice(0, 1000) + "...[truncated]" + : value; } if (typeof value !== "object") return value; @@ -178,7 +180,7 @@ getAttr("data-test") || null; - var type = tag === "input" ? (getAttr("type") || "text") : null; + var type = tag === "input" ? getAttr("type") || "text" : null; var href = tag === "a" ? getAttr("href") || null : null; // a small, stable hint for agents (avoid building full CSS paths) @@ -233,7 +235,8 @@ if (isSensitiveField(el)) return { masked: true, length: v.length }; - if (v.length > CONFIG.uiInputMaxLen) v = v.slice(0, CONFIG.uiInputMaxLen) + "…"; + if (v.length > CONFIG.uiInputMaxLen) + v = v.slice(0, CONFIG.uiInputMaxLen) + "…"; return v; } @@ -456,9 +459,10 @@ init = init || {}; var startTime = Date.now(); // Handle string, Request object, or URL object - var url = typeof input === "string" - ? input - : (input && (input.url || input.href || String(input))) || ""; + var url = + typeof input === "string" + ? input + : (input && (input.url || input.href || String(input))) || ""; var method = init.method || (input && input.method) || "GET"; // Don't intercept internal requests @@ -470,7 +474,9 @@ var requestHeaders = {}; try { if (init.headers) { - requestHeaders = Object.fromEntries(new Headers(init.headers).entries()); + requestHeaders = Object.fromEntries( + new Headers(init.headers).entries() + ); } } catch (e) { requestHeaders = { _parseError: true }; @@ -494,7 +500,9 @@ .then(function (response) { entry.duration = Date.now() - startTime; - var contentType = (response.headers.get("content-type") || "").toLowerCase(); + var contentType = ( + response.headers.get("content-type") || "" + ).toLowerCase(); var contentLength = response.headers.get("content-length"); entry.response = { @@ -516,9 +524,10 @@ } // Skip body capture for streaming responses (SSE, etc.) to avoid memory leaks - var isStreaming = contentType.indexOf("text/event-stream") !== -1 || - contentType.indexOf("application/stream") !== -1 || - contentType.indexOf("application/x-ndjson") !== -1; + var isStreaming = + contentType.indexOf("text/event-stream") !== -1 || + contentType.indexOf("application/stream") !== -1 || + contentType.indexOf("application/x-ndjson") !== -1; if (isStreaming) { entry.response.body = "[Streaming response - not captured]"; store.networkRequests.push(entry); @@ -527,20 +536,25 @@ } // Skip body capture for large responses to avoid memory issues - if (contentLength && parseInt(contentLength, 10) > CONFIG.maxBodyLength) { - entry.response.body = "[Response too large: " + contentLength + " bytes]"; + if ( + contentLength && + parseInt(contentLength, 10) > CONFIG.maxBodyLength + ) { + entry.response.body = + "[Response too large: " + contentLength + " bytes]"; store.networkRequests.push(entry); pruneBuffer(store.networkRequests, CONFIG.bufferSize.network); return response; } // Skip body capture for binary content types - var isBinary = contentType.indexOf("image/") !== -1 || - contentType.indexOf("video/") !== -1 || - contentType.indexOf("audio/") !== -1 || - contentType.indexOf("application/octet-stream") !== -1 || - contentType.indexOf("application/pdf") !== -1 || - contentType.indexOf("application/zip") !== -1; + var isBinary = + contentType.indexOf("image/") !== -1 || + contentType.indexOf("video/") !== -1 || + contentType.indexOf("audio/") !== -1 || + contentType.indexOf("application/octet-stream") !== -1 || + contentType.indexOf("application/pdf") !== -1 || + contentType.indexOf("application/zip") !== -1; if (isBinary) { entry.response.body = "[Binary content: " + contentType + "]"; store.networkRequests.push(entry); @@ -558,7 +572,8 @@ if (text.length <= CONFIG.maxBodyLength) { entry.response.body = sanitizeValue(tryParseJson(text)); } else { - entry.response.body = text.slice(0, CONFIG.maxBodyLength) + "...[truncated]"; + entry.response.body = + text.slice(0, CONFIG.maxBodyLength) + "...[truncated]"; } }) .catch(function () { @@ -615,24 +630,30 @@ xhr._manusData.url.indexOf("/__manus__/") !== 0 ) { xhr._manusData.startTime = Date.now(); - xhr._manusData.requestBody = body ? sanitizeValue(tryParseJson(body)) : null; + xhr._manusData.requestBody = body + ? sanitizeValue(tryParseJson(body)) + : null; xhr.addEventListener("load", function () { - var contentType = (xhr.getResponseHeader("content-type") || "").toLowerCase(); + var contentType = ( + xhr.getResponseHeader("content-type") || "" + ).toLowerCase(); var responseBody = null; // Skip body capture for streaming responses - var isStreaming = contentType.indexOf("text/event-stream") !== -1 || - contentType.indexOf("application/stream") !== -1 || - contentType.indexOf("application/x-ndjson") !== -1; + var isStreaming = + contentType.indexOf("text/event-stream") !== -1 || + contentType.indexOf("application/stream") !== -1 || + contentType.indexOf("application/x-ndjson") !== -1; // Skip body capture for binary content types - var isBinary = contentType.indexOf("image/") !== -1 || - contentType.indexOf("video/") !== -1 || - contentType.indexOf("audio/") !== -1 || - contentType.indexOf("application/octet-stream") !== -1 || - contentType.indexOf("application/pdf") !== -1 || - contentType.indexOf("application/zip") !== -1; + var isBinary = + contentType.indexOf("image/") !== -1 || + contentType.indexOf("video/") !== -1 || + contentType.indexOf("audio/") !== -1 || + contentType.indexOf("application/octet-stream") !== -1 || + contentType.indexOf("application/pdf") !== -1 || + contentType.indexOf("application/zip") !== -1; if (isStreaming) { responseBody = "[Streaming response - not captured]"; @@ -643,7 +664,8 @@ try { var text = xhr.responseText || ""; if (text.length > CONFIG.maxBodyLength) { - responseBody = text.slice(0, CONFIG.maxBodyLength) + "...[truncated]"; + responseBody = + text.slice(0, CONFIG.maxBodyLength) + "...[truncated]"; } else { responseBody = sanitizeValue(tryParseJson(text)); } @@ -817,5 +839,7 @@ forceReport: reportLogs, }; - console.debug("[Manus] Debug collector initialized (no rrweb, UI events only)"); + console.debug( + "[Manus] Debug collector initialized (no rrweb, UI events only)" + ); })(); diff --git a/client/src/App.tsx b/client/src/App.tsx index 5af25ba6..7f0fd849 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -6,12 +6,14 @@ import ErrorBoundary from "./components/ErrorBoundary"; import { ThemeProvider } from "./contexts/ThemeContext"; import Home from "./pages/Home"; import AnalysisWorkspace from "./pages/AnalysisWorkspace"; +import About from "./pages/About"; function Router() { // make sure to consider if you need authentication for certain routes return ( + @@ -27,9 +29,9 @@ function App() { theme="dark" toastOptions={{ style: { - background: 'oklch(0.14 0.01 270)', - border: '1px solid oklch(0.22 0.01 270)', - color: 'oklch(0.92 0.01 80)', + background: "oklch(0.14 0.01 270)", + border: "1px solid oklch(0.22 0.01 270)", + color: "oklch(0.92 0.01 80)", }, }} /> diff --git a/client/src/_core/hooks/useAuth.ts b/client/src/_core/hooks/useAuth.ts index dcef9bd8..74b886d7 100644 --- a/client/src/_core/hooks/useAuth.ts +++ b/client/src/_core/hooks/useAuth.ts @@ -67,7 +67,7 @@ export function useAuth(options?: UseAuthOptions) { if (typeof window === "undefined") return; if (window.location.pathname === redirectPath) return; - window.location.href = redirectPath + window.location.href = redirectPath; }, [ redirectOnUnauthenticated, redirectPath, diff --git a/client/src/components/AIChatBox.tsx b/client/src/components/AIChatBox.tsx index 1c00871f..52b235fe 100644 --- a/client/src/components/AIChatBox.tsx +++ b/client/src/components/AIChatBox.tsx @@ -127,7 +127,7 @@ export function AIChatBox({ const textareaRef = useRef(null); // Filter out system messages - const displayMessages = messages.filter((msg) => msg.role !== "system"); + const displayMessages = messages.filter(msg => msg.role !== "system"); // Calculate min-height for last assistant message to push user message to top const [minHeightForLastMessage, setMinHeightForLastMessage] = useState(0); @@ -143,7 +143,8 @@ export function AIChatBox({ // - user message: 40px (item height) + 16px (margin-top from space-y-4) = 56px // Note: margin-bottom is not counted because it naturally pushes the assistant message down const userMessageReservedHeight = 56; - const calculatedHeight = scrollAreaHeight - 32 - userMessageReservedHeight; + const calculatedHeight = + scrollAreaHeight - 32 - userMessageReservedHeight; setMinHeightForLastMessage(Math.max(0, calculatedHeight)); } @@ -152,14 +153,14 @@ export function AIChatBox({ // Scroll to bottom helper function with smooth animation const scrollToBottom = () => { const viewport = scrollAreaRef.current?.querySelector( - '[data-radix-scroll-area-viewport]' + "[data-radix-scroll-area-viewport]" ) as HTMLDivElement; if (viewport) { requestAnimationFrame(() => { viewport.scrollTo({ top: viewport.scrollHeight, - behavior: 'smooth' + behavior: "smooth", }); }); } @@ -311,7 +312,7 @@ export function AIChatBox({