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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
needs: [build]
services:
postgres:
image: pgvector/pgvector:pg16
image: pgvector/pgvector:pg17
env:
POSTGRES_DB: postgres_dev
POSTGRES_USER: dev_user
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

- Use any testing tools, libraries available to the project for testing your changes
- Never assume your changes simply work, always test!
- This project uses **Playwright** for end-to-end tests in `e2e/`. Run them with `pnpm test:e2e`. Add a test for new user-facing flows.
- This project uses **Playwright** for end-to-end tests in `e2e/`. They run against your local database (`POSTGRES_URL` from `.env`) — start it with `podman compose up -d` and run `pnpm db:migrate` first, then `pnpm test:e2e`. Add a test for new user-facing flows.
- If the project does not have any testing tools, scripts, MCP tools, skills, etc. available for testing, ask the user whether testing should be skipped.

## STACK
Expand All @@ -45,7 +45,7 @@

## DEPLOYMENT

- The app builds to a standalone server (`output: "standalone"`) with a `Dockerfile`; it targets any Docker- or Podman-compatible host (Coolify, Hetzner, VPS). The same `Dockerfile` and `docker-compose.yml` work unchanged with `podman build` / `podman compose`.
- The app builds to a standalone server (`output: "standalone"`) with a `Dockerfile`; it targets any Docker- or Podman-compatible host (Coolify, Hetzner, VPS). The same `Dockerfile` and `compose.yml` work unchanged with `podman build` / `podman compose`.
- Do **not** run database migrations during the build. `pnpm build` is `next build` only. Run `pnpm db:migrate` as a separate release/pre-deploy step.

## UI DESIGN
Expand Down
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Then configure and run the app:

```bash
cp env.example .env
docker compose up -d # or: podman compose up -d
podman compose up -d # or: docker compose up -d
pnpm db:migrate
pnpm dev
```
Expand Down Expand Up @@ -113,7 +113,7 @@ OPENROUTER_MODEL="openai/gpt-5-mini"
OPENAI_EMBEDDING_MODEL="text-embedding-3-large"
```

For local development, the default database URL works with the included `docker-compose.yml`. For production, use the database URL from your hosting provider.
For local development, the default database URL works with the included `compose.yml`. For production, use the database URL from your hosting provider.

Generate a strong `BETTER_AUTH_SECRET` before deploying. The starter ships with a development value only so you can get moving quickly.

Expand Down Expand Up @@ -263,7 +263,7 @@ Important root files:
- `CLAUDE.md`: Claude entrypoint for the same guidance
- `DESIGN.md`: UI design system and component guidance
- `drizzle.config.ts`: Drizzle migration configuration
- `docker-compose.yml`: local PostgreSQL service
- `compose.yml`: local PostgreSQL service
- `env.example`: environment variable template
- `components.json`: shadcn/ui configuration

Expand Down Expand Up @@ -300,7 +300,7 @@ Do not use schema push as a replacement for migrations in real project work.
For local development:

```bash
docker compose up -d # or: podman compose up -d
podman compose up -d # or: docker compose up -d
pnpm db:migrate
```

Expand Down Expand Up @@ -374,14 +374,22 @@ On Coolify, configure this as a pre-deploy command; in CI, run it behind a manua

## Testing

End-to-end tests live in `e2e/` and run with Playwright:
End-to-end tests live in `e2e/` and run with Playwright against your local
database (the `POSTGRES_URL` from `.env`). Make sure the database is running and
migrated first:

```bash
pnpm exec playwright install # one-time: download browsers
podman compose up -d # or: docker compose up -d
pnpm db:migrate
pnpm test:e2e
```

The Playwright config starts the dev server automatically for local runs. In CI, a PostgreSQL service is provisioned, migrations are applied, and the smoke tests run after the build (see `.github/workflows/ci.yml`).
Playwright starts the dev server automatically for local runs. The suite
includes a real register → sign-out → sign-in flow (using a unique email per
run) alongside the static smoke tests. In CI, a PostgreSQL service is
provisioned, migrations are applied, and the suite runs after the build (see
`.github/workflows/ci.yml`).

## Troubleshooting

Expand All @@ -390,7 +398,7 @@ The Playwright config starts the dev server automatically for local runs. In CI,
Confirm Docker (or Podman) is running and start the database:

```bash
docker compose up -d # or: podman compose up -d
podman compose up -d # or: docker compose up -d
```

Then check that `POSTGRES_URL` in `.env` matches the database connection string.
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml → compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
services:
postgres:
# Pin the major version to match your production database (e.g. Coolify/Hetzner).
image: pgvector/pgvector:pg16
image: pgvector/pgvector:pg17
environment:
POSTGRES_DB: postgres_dev
POSTGRES_USER: dev_user
Expand Down
38 changes: 38 additions & 0 deletions e2e/auth.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect, test } from "@playwright/test";

/**
* Database-backed flow: register a fresh account (which auto-signs-in and lands
* on the dashboard), sign out by clearing the session cookie, then sign back in
* with the same credentials. Exercises Better Auth + Postgres end to end.
*/
test("register, sign out, and sign back in", async ({ page }) => {
// Unique email per run so the test is repeatable against a persistent DB.
const email = `e2e-${Date.now()}@example.com`;
const password = "test-password-123";

// --- Register -----------------------------------------------------------
await page.goto("/register");
await page.getByLabel("Name").fill("E2E Test User");
await page.getByLabel("Email").fill(email);
await page.getByLabel("Password", { exact: true }).fill(password);
await page.getByLabel("Confirm Password").fill(password);
await page.getByRole("button", { name: "Create account" }).click();

// Successful sign-up redirects to the protected dashboard.
await expect(page).toHaveURL(/\/dashboard$/);
await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();

// --- Sign out (drop the session cookie) ---------------------------------
await page.context().clearCookies();

// --- Sign back in -------------------------------------------------------
// Scope to the page form: the header also has a "Sign in" button when logged out.
const signInForm = page.locator("#main-content");
await page.goto("/login");
await signInForm.getByLabel("Email").fill(email);
await signInForm.getByLabel("Password", { exact: true }).fill(password);
await signInForm.getByRole("button", { name: "Sign in" }).click();

await expect(page).toHaveURL(/\/dashboard$/);
await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
});
7 changes: 5 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ export default defineConfig({
use: { ...devices["Desktop Chrome"] },
},
],
// Starts the app for local runs. In CI, start the server in a separate step
// and point PLAYWRIGHT_BASE_URL at it, or let this reuse it.
// Starts the app for local runs against the database from your .env
// (POSTGRES_URL). Make sure the dev database is running and migrated first:
// podman compose up -d # or: docker compose up -d
// pnpm db:migrate
// In CI, start the server in a separate step and point PLAYWRIGHT_BASE_URL at it.
webServer: {
command: "pnpm dev",
url: baseURL,
Expand Down
Loading