Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@ costs cents per month at idle.

---

> **Status — Phase 5 complete; Phase 6 (production deploy) in progress.**
> The full MVP is live on AWS (`sa-east-1`): JWT auth + multi-tenant orgs,
> document upload to S3 via presigned URLs, an async AI pipeline (extract →
> **Status — MVP live (Phases 0–6 complete).**
> The full MVP is deployed: the Angular SPA on Vercel talks to a serverless API
> on AWS (`sa-east-1`) backed by Neon Postgres. Features: JWT auth + multi-tenant
> orgs, document upload to S3 via presigned URLs, an async AI pipeline (extract →
> summarize → classify with `gpt-4o-mini`), full-text search and a metrics
> dashboard. The Angular SPA covers auth, upload, document detail with live AI
> results, search/filters and the dashboard. Phase 6 wires the frontend to
> Vercel for a public demo URL.
> dashboard. Next up (Phase 7+): embeddings + semantic search, RAG chat, folders,
> Stripe billing and OCR.

<!-- Live demo: set once the Vercel deploy is connected, e.g. https://clouddocs.vercel.app -->

**Live demo:** _coming soon (Vercel)._ · **API:** `https://ngm5oizp91.execute-api.sa-east-1.amazonaws.com/v1/health`
**Live demo:** https://cloud-docs-theta.vercel.app · **API health:** `https://ngm5oizp91.execute-api.sa-east-1.amazonaws.com/v1/health`

## Why this exists

Expand Down Expand Up @@ -130,16 +128,16 @@ runs Prettier + ESLint on staged files via Husky pre-commit hooks.
The work is sequenced into publishable phases. Each phase produces something
demoable so the project never sits half-finished.

| Phase | Theme | Status |
| ----- | ---------------------------------------------- | -------------- |
| 0 | Workspace, tooling, libs, healthcheck handler | ✅ Done |
| 1 | CDK stacks (S3, API GW, observability) | ✅ Done |
| 2 | Auth + multi-tenant orgs (API + frontend UI) | ✅ Done |
| 3 | Upload + S3 storage | ✅ Done |
| 4 | AI pipeline (extract → summarize → classify) | ✅ Done |
| 5 | Dashboard + full-text search | ✅ Done |
| 6 | Polish + production deploy (frontend → Vercel) | 🟡 In progress |
| 7+ | Embeddings + RAG chat + folders + Stripe + OCR | ⏳ |
| Phase | Theme | Status |
| ----- | ---------------------------------------------- | ------- |
| 0 | Workspace, tooling, libs, healthcheck handler | ✅ Done |
| 1 | CDK stacks (S3, API GW, observability) | ✅ Done |
| 2 | Auth + multi-tenant orgs (API + frontend UI) | ✅ Done |
| 3 | Upload + S3 storage | ✅ Done |
| 4 | AI pipeline (extract → summarize → classify) | ✅ Done |
| 5 | Dashboard + full-text search | ✅ Done |
| 6 | Polish + production deploy (frontend → Vercel) | ✅ Done |
| 7+ | Embeddings + RAG chat + folders + Stripe + OCR | ⏳ |

See [`docs/plan.md`](docs/plan.md) for the detailed architecture, data model,
security model and AWS free-tier strategy.
Expand Down
14 changes: 14 additions & 0 deletions apps/web-e2e/src/auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ async function stubAnonymousBoot(page: Page): Promise<void> {
);
}

test('landing page links to register and login', async ({ page }) => {
await stubAnonymousBoot(page);

await page.goto('/');
// Hero CTA → register.
await page.getByTestId('hero-cta').click();
await expect(page).toHaveURL(/\/auth\/register/);

// Topbar "Sign in" → login.
await page.goto('/');
await page.getByTestId('nav-signin').click();
await expect(page).toHaveURL(/\/auth\/login/);
});

test('guests are redirected from a protected route to login', async ({ page }) => {
await stubAnonymousBoot(page);

Expand Down
35 changes: 23 additions & 12 deletions apps/web/src/app/features/landing/landing.page.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { RouterLink } from '@angular/router';

@Component({
selector: 'app-landing',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [RouterLink],
template: `
<main class="relative min-h-screen overflow-hidden">
<!-- Background gradient mesh -->
Expand Down Expand Up @@ -31,12 +33,22 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
alpha
</span>
</div>
<nav class="hidden items-center gap-6 text-sm text-text-muted md:flex">
<a class="hover:text-text" href="#features">Features</a>
<a class="hover:text-text" href="#architecture">Architecture</a>
<a class="hover:text-text" href="https://github.com" target="_blank" rel="noreferrer"
>GitHub</a
<nav class="flex items-center gap-4 text-sm md:gap-6">
<a class="hidden text-text-muted hover:text-text md:inline" href="#features"
>Features</a
>
<a
routerLink="/auth/login"
class="text-text-muted transition hover:text-text"
data-testid="nav-signin"
>Sign in</a
>
<a
routerLink="/auth/register"
class="inline-flex h-9 items-center justify-center rounded-lg bg-brand-500 px-4 text-sm font-semibold text-white shadow-[0_0_24px_rgba(124,92,255,0.25)] transition hover:bg-brand-400"
>
Get started
</a>
</nav>
</div>
</header>
Expand All @@ -48,7 +60,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
class="mb-6 inline-flex items-center gap-2 rounded-full border border-border bg-surface-2/60 px-3 py-1 text-xs font-medium text-text-muted backdrop-blur"
>
<span class="h-1.5 w-1.5 rounded-full bg-emerald-400"></span>
Phase 0 · Workspace bootstrapped
Live · upload, AI summaries & search
</div>

<h1 class="text-5xl font-bold tracking-tight text-text sm:text-6xl lg:text-7xl">
Expand All @@ -68,18 +80,17 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';

<div class="mt-10 flex flex-wrap items-center gap-4">
<a
href="#features"
routerLink="/auth/register"
data-testid="hero-cta"
class="inline-flex h-11 items-center justify-center rounded-lg bg-brand-500 px-6 text-sm font-semibold text-white shadow-[0_0_24px_rgba(124,92,255,0.25)] transition hover:bg-brand-400"
>
Explore features
Get started — it's free
</a>
<a
href="https://github.com"
target="_blank"
rel="noreferrer"
href="#features"
class="inline-flex h-11 items-center justify-center rounded-lg border border-border bg-surface-2/60 px-6 text-sm font-semibold text-text backdrop-blur transition hover:border-border-strong hover:bg-surface-3"
>
View source ↗
Explore features
</a>
</div>
</div>
Expand Down
6 changes: 5 additions & 1 deletion apps/web/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>web</title>
<title>CloudDocs AI — Intelligent document management</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="Upload PDFs and DOCX files. CloudDocs AI extracts, summarizes and classifies them with AI, and lets you search your knowledge base."
/>
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
Expand Down
Loading