AI-assisted project operations for engineering teams, with tasks, timelines, chat, document context, repo activity, reporting, and cross-project coordination in one workspace.
Odyssey is a full-stack application, not just a React frontend. The repository includes:
- a Vite + React client in
client/ - a Fastify API server in
server/ - a Supabase schema and migration set in
supabase/ - a self-hosted Supabase deployment in
deploy/supabase/ - a root Docker Compose deployment for Odyssey and the bundled Supabase stack
The current codebase expects Supabase features directly:
- Auth
- Postgres
- Storage
- Realtime
- RLS
- RPC-backed project and invite flows
A plain PostgreSQL database is not a drop-in replacement.
Core product areas in the current codebase:
- multi-project dashboard with AI summaries and project health
- detailed project pages with tabs for overview, timeline, tasks, activity, coordination, metrics, financials, reports, documents, integrations, and settings
- task tracking with dependencies, multi-assignee support, comments, AI guidance, time logging, categories, LOE, deadlines, and status/risk tracking
- global and project-scoped chat, including direct messages
- AI-generated project insights, standups, intelligent updates, and report generation
- GitHub and GitLab repository linking, commit activity, repo browsing, and file previews
- Microsoft 365 import flows for documents and notes
- invite-code, QR invite, private project, join-request, and shared access workflows
- theme support, including NPS-branded themes and several non-NPS themes
flowchart LR
B[Browser] --> C[React Client]
C --> A[Fastify API]
C --> S[(Supabase)]
A --> S
A --> AI[Anthropic / OpenAI / Gemini / Azure OpenAI]
A --> GH[GitHub API]
A --> GL[GitLab API]
A --> MS[Microsoft Graph]
In development:
- the client usually runs on
http://localhost:5173 - the API usually runs on
http://localhost:3000 - Vite proxies
/apiand/supabaseto the Fastify server
In production:
- the React app is built into static assets
- Fastify serves the built client and API from the same container
- Supabase runs as a separate compose stack
The checked-in production path is container-based and built around these pieces:
- compose.yaml Loads the complete Supabase and Odyssey deployment from the repository root.
- Dockerfile Builds the client, builds the server, then produces one runtime image that serves both.
- deploy/Dockerfile.migrations Packages the checked-in schema and migrations as a one-shot Compose service.
- deploy/docker-compose.odyssey.yml Runs the migration and Odyssey app containers and wires them to Supabase.
- deploy/supabase/docker-compose.yml Runs the self-hosted Supabase services.
- scripts/vm/up.sh Compatibility/setup wrapper that refreshes the derived Supabase env before running Compose.
- scripts/vm/down.sh Stops the stack.
- scripts/vm/generate-supabase-env.sh Syncs Odyssey app settings into the Supabase env, including auth redirect URLs.
The production container exposes port 3000. Supabase services are exposed through the bundled gateway/proxy layer and are also routed back to the browser under /supabase.
odyssey/
compose.yaml Root entry point for the full production stack
client/ React 19 + Vite frontend
server/ Fastify 5 API server
supabase/ Base schema and app migrations
deploy/
docker-compose.odyssey.yml
odyssey.env.example
supabase/ Self-hosted Supabase stack
scripts/docker/ In-container database migration runner
scripts/vm/ Environment setup and export/import helpers
setup.md Longer setup and deployment guide
Important frontend entry points:
- client/src/pages/DashboardPage.tsx
- client/src/pages/ProjectDetailPage.tsx
- client/src/pages/ChatPage.tsx
- client/src/pages/LoginPage.tsx
- client/src/components/project-tabs/OverviewTab.tsx
- client/src/components/project-tabs/ActivityTab.tsx
- client/src/components/Timeline.tsx
- client/src/components/CommitActivityCharts.tsx
Important backend entry points:
- server/src/index.ts
- server/src/routes/ai.ts
- server/src/routes/auth.ts
- server/src/routes/github.ts
- server/src/routes/gitlab.ts
- server/src/routes/microsoft.ts
- server/src/routes/uploads.ts
- server/src/routes/coordination.ts
Important database areas:
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Vite 8, Tailwind CSS 4 |
| Backend | Node.js, Fastify 5, TypeScript |
| Auth / DB / Storage / Realtime | Supabase |
| AI providers | Anthropic, OpenAI, Google Gemini, Azure OpenAI |
| Repo integrations | GitHub, GitLab |
| Microsoft integration | Microsoft Graph |
| Document tooling | pdf-parse, mammoth, docx, jspdf, pptxgenjs, exceljs |
Use this when you are building features or debugging.
Typical process:
- run Fastify from
server/ - run Vite from
client/ - point both at a Supabase project or local Supabase stack
Typical URLs:
http://localhost:5173for the clienthttp://localhost:3000for the API
Use this when you want Odyssey and Supabase running together on one machine.
Typical process:
- create
deploy/odyssey.env - generate
deploy/supabase/.envonce for the host - run
docker compose up -d --build
This is the most accurate way to run the repo as designed.
- Install Node.js 22 or newer, npm, Docker, and Docker Compose.
- Clone the repo.
- Install dependencies in
client/andserver/. - Create a Supabase backend, either cloud-hosted or local/self-hosted.
- Apply supabase/schema.sql and all migrations in supabase/.
- Create
client/.env.local. - Create
server/.env. - Start the server and client.
Client env:
VITE_SUPABASE_URL=https://YOUR_PROJECT.supabase.co
VITE_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
VITE_API_URL=http://127.0.0.1:3000Server env:
NODE_ENV=development
HOST=0.0.0.0
PORT=3000
SUPABASE_URL=https://YOUR_PROJECT.supabase.co
SUPABASE_SERVICE_KEY=YOUR_SUPABASE_SERVICE_ROLE_KEY
CLIENT_URL=http://localhost:5173
CLIENT_DIST_PATH=
ANTHROPIC_API_KEY=
OPENAI_API_KEY=
GOOGLE_AI_API_KEY=
AZURE_OPENAI_API_KEY=
AZURE_OPENAI_BASE_URL=
AZURE_OPENAI_MODEL=
GITHUB_TOKEN=
GITHUB_WEBHOOK_SECRET=
MICROSOFT_CLIENT_ID=
MICROSOFT_CLIENT_SECRET=
MICROSOFT_TENANT_URL=https://login.microsoftonline.com/common
MICROSOFT_REDIRECT_URI=http://localhost:3000/api/microsoft/auth/callback
MICROSOFT_TOKEN_ENCRYPT_KEY=
ZOTERO_CLIENT_KEY=
ZOTERO_CLIENT_SECRET=
ZOTERO_REDIRECT_URI=http://localhost:3000/api/zotero/auth/callback
ZOTERO_TOKEN_ENCRYPT_KEY=
AI_KEY_SECRET=Before exposing Odyssey to real users, verify these deployment controls:
- set
AI_KEY_SECRET,MICROSOFT_TOKEN_ENCRYPT_KEY, andZOTERO_TOKEN_ENCRYPT_KEY; do not rely onSUPABASE_SERVICE_KEYfor token encryption - set
GITHUB_WEBHOOK_SECRETand reject unsigned webhook traffic - set
CLIENT_URLto the exact trusted browser origin and avoid wildcard origins in reverse proxies or storage gateways - keep the
goal-attachmentsbucket private and review Supabase Storage policies before importing production data - keep service-role credentials server-only; never expose
SUPABASE_SERVICE_KEYoutside the Fastify container or admin scripts - set reverse-proxy body limits to match Odyssey’s stricter server limits rather than allowing arbitrary uploads
- restrict
/supabase/*exposure to the browser-facing auth, rest, realtime, and storage paths only - rotate provider, webhook, and storage credentials if they were ever used with older insecure defaults
Commands:
cd client && npm install
cd ../server && npm install
cd ../server && npm run dev
cd ../client && npm run dev- Install Docker and Docker Compose 2.24.7 or newer (the root model uses Compose
includewith its long syntax). - Copy deploy/odyssey.env.example to
deploy/odyssey.env. - Update
CLIENT_URLand any provider/integration settings. - Generate the host-specific Supabase environment once.
- Start the full stack from the repository root.
cp deploy/odyssey.env.example deploy/odyssey.env
# Edit deploy/odyssey.env before continuing.
bash scripts/vm/generate-supabase-env.sh
docker compose up -d --buildCompose will:
- build the Odyssey runtime image
- start Supabase and Odyssey together
- run all pending Odyssey database migrations
- wait for the database migrations and Supabase gateway before starting Odyssey
Run generate-supabase-env.sh again only when host URLs, auth providers, or related environment settings change. Routine code deployments do not need it.
After pushing changes, the complete VM deployment command is:
git pull --ff-only && docker compose up -d --build --remove-orphansTo stop the stack:
docker compose downThis repository can be used outside NPS. The NPS-specific branding and sample values are not hard requirements.
For a non-NPS deployment:
- set
CLIENT_URLto your own hostname or local URL - use
MICROSOFT_TENANT_URL=https://login.microsoftonline.com/commonunless you have a tenant-specific reason not to - set
MICROSOFT_REDIRECT_URIto your own Odyssey host, for examplehttps://your-domain.example/api/microsoft/auth/callback - supply your own GitHub, GitLab, Google, Microsoft, and AI credentials
- do not rely on any checked-in NPS hostnames or example tenant IDs
Important clarification:
- names like
GITLAB_NPS_HOSTin the example env are legacy/example naming, not a hard dependency on NPS - the live GitLab integration is project-driven and stores the actual GitLab host and repo URL in integration config
- NPS themes are optional UI themes, not deployment requirements
If you are standing up a brand-new non-NPS install, start from deploy/odyssey.env.example, not from an environment file that already contains organization-specific values.
Main file for the containerized deployment:
deploy/odyssey.env
Common keys:
CLIENT_URLANTHROPIC_API_KEYOPENAI_API_KEYGOOGLE_AI_API_KEYAZURE_OPENAI_API_KEYAZURE_OPENAI_BASE_URLAZURE_OPENAI_MODELGITHUB_TOKENGITHUB_WEBHOOK_SECRETGITHUB_OAUTH_CLIENT_IDGITHUB_OAUTH_CLIENT_SECRETGOOGLE_OAUTH_CLIENT_IDGOOGLE_OAUTH_CLIENT_SECRETMICROSOFT_CLIENT_IDMICROSOFT_CLIENT_SECRETMICROSOFT_TENANT_URLMICROSOFT_REDIRECT_URIMICROSOFT_TOKEN_ENCRYPT_KEYZOTERO_CLIENT_KEYZOTERO_CLIENT_SECRETZOTERO_REDIRECT_URIZOTERO_TOKEN_ENCRYPT_KEY
Register a Zotero OAuth application at https://www.zotero.org/oauth/apps. The callback must be the public Odyssey URL plus /api/zotero/auth/callback; for this deployment that is https://asterias.ssag.nps.edu/odyssey/api/zotero/auth/callback. Generate ZOTERO_TOKEN_ENCRYPT_KEY with openssl rand -hex 32 and keep it server-only.
Imported Zotero attachments are indexed for Sources search and query-relevant Thesis AI retrieval without retaining a duplicate file in Odyssey storage. Source and attachment actions open Zotero Desktop through zotero:// links, with Zotero Web Library fallbacks. Odyssey prefers Zotero's own full-text index, then temporarily downloads a file for PDF, DOCX, or text extraction and discards it after indexing. Image-only PDFs use Poppler plus Tesseract OCR (up to the first 20 pages); both tools are included in the production Docker image. Install poppler-utils and tesseract-ocr on a non-Docker development host to exercise the OCR fallback there. Potential credentials and restricted sources remain excluded from Thesis AI until the user explicitly approves them.
Generated file:
deploy/supabase/.env
This file is partly managed by scripts/vm/generate-supabase-env.sh. It sets:
- Supabase public URL
- site URL
- redirect URLs
- provider enablement flags for Supabase Auth
- generated keys when missing
Do not treat this as a purely hand-maintained file. Refresh it with scripts/vm/generate-supabase-env.sh when host or authentication settings change; routine Compose rebuilds reuse it.
Odyssey currently supports:
- Supabase Auth
- username/password auth flows built on top of Supabase
- Google OAuth through Supabase Auth when configured
- Microsoft account linking and Microsoft Graph document access when configured
For production use, verify these are aligned:
CLIENT_URL- Supabase
SITE_URL - Supabase redirect URLs
- Microsoft redirect URI
- any OAuth provider callback URLs
The environment generator aligns these settings during initial setup and whenever authentication configuration changes.
Supports:
- repository linking
- commit activity
- file tree browsing
- file preview
- webhook-backed activity ingestion
- AI context from linked repos
Supports:
- repository linking by full repo URL
- per-project repo host tracking
- encrypted per-user project tokens
- commit activity
- file tree browsing
- file preview
- AI context from linked repos
The checked-in code no longer assumes a single global GitLab host.
Supports:
- Microsoft sign-in/account linking
- OneDrive browsing and import
- OneNote content access
- Graph-backed document ingestion
For non-NPS users, the main requirement is your own Azure app registration. The code does not require an NPS tenant.
npm run dev
npm run build
npm run lint
npm run previewnpm run dev
npm run build
npm run startdocker compose up -d --build
docker compose downAfter setup, verify all of these before calling the environment healthy:
- sign in works
- project creation works
- task create/edit works
- the dashboard loads project data
- the project overview and timeline load
- AI chat works with at least one configured provider
- contributor and activity views load without auth errors
- GitHub or GitLab linking works
- repo commit activity appears when repos are linked
- Microsoft import works if Microsoft integration is enabled
- reports can be generated and saved
- invites and join flows work
- setup.md for the longer operator guide
- deploy/VM_MIGRATION.md for VM-oriented notes
- deploy/supabase/README.md for the bundled Supabase stack
No explicit open-source license is declared in this repository. If you plan to distribute it outside your organization, add the appropriate license and policy files first.