Skip to content

Commit 809a4b7

Browse files
authored
Merge pull request #10 from BjornMelin/feat/neon-postgres-drizzle-orm
feat: align architecture and env config with Neon Postgres and Fluid compute stack
2 parents 1f19711 + b683427 commit 809a4b7

70 files changed

Lines changed: 8025 additions & 84 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ AUTH_ALLOWED_EMAILS=
2525
# Vercel OAuth callback URL allowlisting (Neon Auth uses a branch-specific callback URL).
2626
NEXT_PUBLIC_AUTH_SOCIAL_PROVIDERS=vercel
2727

28+
# App base URL (used for server-to-server callbacks like QStash)
29+
APP_BASE_URL=
30+
2831
# Database (Neon Postgres)
2932
DATABASE_URL=
3033

@@ -42,9 +45,12 @@ QSTASH_CURRENT_SIGNING_KEY=
4245
QSTASH_NEXT_SIGNING_KEY=
4346
QSTASH_TOKEN=
4447

45-
# Vercel AI Gateway (OpenAI-compatible)
48+
# Vercel AI Gateway
4649
AI_GATEWAY_API_KEY=
47-
AI_GATEWAY_BASE_URL=https://ai-gateway.vercel.sh/v1
50+
AI_GATEWAY_BASE_URL=https://ai-gateway.vercel.sh/v3/ai
51+
# Optional: default model IDs for the app (AI Gateway model IDs)
52+
AI_GATEWAY_CHAT_MODEL=xai/grok-4.1-fast-reasoning
53+
AI_GATEWAY_EMBEDDING_MODEL=alibaba/qwen3-embedding-4b
4854

4955
# Vercel Blob (uploads)
5056
BLOB_READ_WRITE_TOKEN=

AGENTS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ bun run fetch:models # Update AI model catalog (requires AI_GATEWAY_AP
3737

3838
## Drizzle + database
3939

40-
- `drizzle.config.ts` reads `DATABASE_URL` at runtime; `bun run db:*` commands will fail fast if it's missing.
40+
- `drizzle.config.ts` loads Next.js `.env*` files and requires `DATABASE_URL` for
41+
commands that need a live DB connection (e.g. `db:migrate`, `db:studio`).
4142
- Schema lives in `src/db/schema.ts` and migrations are generated into `src/db/migrations`.
43+
- Runtime DB access uses Postgres TCP with pooling (`pg`) and Drizzle
44+
(`drizzle-orm/node-postgres`). On Vercel Fluid compute, the pool is attached
45+
with `attachDatabasePool` (`@vercel/functions`) in `src/db/client.ts`.
4246

4347
## Database
4448

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ flowchart LR
4646
- Auth: Neon Auth (managed auth + UI components)
4747
- AI: Vercel AI SDK v6 + AI Gateway
4848
- DB: Neon Postgres + Drizzle ORM
49+
- DB connectivity (Vercel): Postgres TCP + connection pooling (`pg`) with
50+
`attachDatabasePool` (`@vercel/functions`) for Fluid compute
51+
([Vercel Functions package](https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package),
52+
[Vercel KB: Connection Pooling with Vercel Functions](https://vercel.com/kb/guide/connection-pooling-with-functions))
4953
- Infra helpers: Upstash (Redis, QStash, Vector)
5054
- Quality: Biome (format/lint) + ESLint (TSDoc/JSDoc enforcement) + Vitest
5155
- Typing/Schema: Zod v4
@@ -101,6 +105,23 @@ bun install
101105
bun run dev
102106
```
103107

108+
### Database migrations
109+
110+
Generate migrations (does not require a live DB connection):
111+
112+
```bash
113+
bun run db:generate
114+
```
115+
116+
Apply migrations (requires `DATABASE_URL`):
117+
118+
```bash
119+
bun run db:migrate
120+
```
121+
122+
Integration tests in `tests/integration/db.test.ts` run only when `DATABASE_URL`
123+
is set; otherwise they are skipped.
124+
104125
Optional: implementation/deploy automation variables (GitHub/Vercel/Neon/Upstash)
105126
are documented in [`docs/ops/env.md`](./docs/ops/env.md).
106127

@@ -149,6 +170,10 @@ bun run test
149170
bun run build
150171
```
151172

173+
Tests are colocated under `src/**` (including route handler tests in
174+
`src/app/api/**/__tests__`) with integration tests under
175+
`tests/integration`.
176+
152177
## Releases and versioning
153178

154179
This repo uses Release Please and Conventional Commits.

bun.lock

Lines changed: 1279 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/architecture/adr/ADR-0003-database-neon-postgres-drizzle-orm.md

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
---
22
ADR: 0003
3-
Title: Database: Neon Postgres + Drizzle ORM
3+
Title: Database - Neon Postgres + Drizzle ORM
44
Status: Accepted
5-
Version: 0.2
6-
Date: 2026-01-30
5+
Version: 0.4
6+
Date: 2026-02-03
77
Supersedes: []
88
Superseded-by: []
99
Related: [ADR-0004, ADR-0005, ADR-0016]
1010
Tags: [architecture, data]
1111
References:
12-
- [Neon serverless driver](https://neon.com/docs/serverless/serverless-driver)
12+
- [Neon: Connecting to Neon from Vercel](https://neon.com/docs/guides/vercel-connection-methods)
13+
- [Vercel: attachDatabasePool](https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package)
1314
- [Neon + Drizzle guide](https://neon.com/docs/guides/drizzle)
1415
- [Drizzle connect Neon](https://orm.drizzle.team/docs/connect-neon)
16+
- [Drizzle connect overview (node-postgres)](https://orm.drizzle.team/docs/connect-overview)
1517
- [Neon on Vercel](https://vercel.com/marketplace/neon)
18+
- [Neon serverless driver (HTTP/WebSocket)](https://neon.com/docs/serverless/serverless-driver)
1619
---
1720

1821
## Status
@@ -23,6 +26,10 @@ Accepted — 2026-01-30.
2326

2427
Use Neon Postgres for relational persistence and Drizzle for schema/migrations.
2528

29+
See [SPEC-0021](../spec/SPEC-0021-full-stack-finalization-fluid-compute-neon-upstash-ai-elements.md)
30+
for the cross-cutting “finalization” plan that ties DB, ingestion, retrieval,
31+
durable runs, and UI together.
32+
2633
## Context
2734

2835
We need durable storage for projects, files, runs, steps, artifacts, and chat state. Neon provides a serverless-friendly driver for Vercel deployments and strong DX via marketplace integration. Drizzle provides type-safe schema and migrations with low boilerplate. The repo is already configured via `drizzle.config.ts` to use `src/db/schema.ts`.
@@ -37,7 +44,7 @@ We need durable storage for projects, files, runs, steps, artifacts, and chat st
3744

3845
## Alternatives
3946

40-
- A: Neon + Drizzle — Pros: strong DX; serverless driver. Cons: Drizzle learning curve.
47+
- A: Neon + Drizzle — Pros: strong DX; Vercel-aligned pooling; serverless driver available where pooling isn’t safe. Cons: Drizzle learning curve.
4148
- B: Neon + Prisma — Pros: popular. Cons: heavier generated layer.
4249
- C: SQLite — Pros: local simplicity. Cons: poor cloud/serverless fit.
4350

@@ -54,7 +61,15 @@ We need durable storage for projects, files, runs, steps, artifacts, and chat st
5461

5562
## Decision
5663

57-
We will adopt **Neon Postgres** with the **Neon serverless driver** and **Drizzle ORM** for schema and migrations.
64+
We will adopt **Neon Postgres** with **Drizzle ORM** for schema and migrations.
65+
66+
Connection method policy:
67+
68+
- On Vercel **Fluid compute**, use Postgres TCP with a connection pool (`pg`)
69+
and attach the pool via `attachDatabasePool`.
70+
- Implementation: `src/db/client.ts`
71+
- In classic serverless environments where safe pooling is unavailable, Neon’s
72+
HTTP/WebSocket serverless driver is an acceptable alternative.
5873

5974
## Constraints
6075

@@ -98,22 +113,35 @@ flowchart LR
98113

99114
- `src/db/schema.ts`: schema definitions.
100115
- `src/db/migrations/`: generated migrations.
101-
- `src/db/client.ts`: Neon driver + Drizzle instance (to add).
116+
- `src/db/client.ts`: Neon driver + Drizzle instance (implemented).
117+
- `src/lib/data/*.server.ts`: server-only Data Access Layer (DAL) modules that
118+
encapsulate all DB reads/writes (implemented).
102119

103120
### Implementation Details
104121

105122
- UUID PKs, timestamps.
106123
- JSONB for citations and usage.
107124
- Index hot fields (`project_id`, `run_id`, `step_name`).
125+
- Runtime driver: Postgres TCP with pooling (Vercel Fluid compute recommendation).
126+
- `pg` (node-postgres) + `drizzle-orm/node-postgres`.
127+
- On Vercel, we attach the pool using `@vercel/functions` to align with
128+
Vercel’s pooling semantics.
129+
- In classic serverless environments where connection pooling is unsafe,
130+
`@neondatabase/serverless` (HTTP/WebSocket) remains a viable alternative.
108131

109132
## Testing
110133

111134
- Integration: migration apply + CRUD.
112135
- Regression: idempotent step updates maintain consistency.
136+
- Integration tests live in `tests/integration/db.test.ts` and run only when
137+
`DATABASE_URL` is available.
113138

114139
## Implementation Notes
115140

116-
- Prefer short-lived connections via serverless driver; avoid long pooled TCP connections in serverless.
141+
- Prefer pooled Postgres TCP connections on Vercel Fluid compute (recommended).
142+
- Keep pool sizes conservative to avoid exhausting Neon connection limits.
143+
- If deploying to a classic serverless platform without safe pooling, switch to
144+
the Neon serverless driver (HTTP/WebSocket).
117145

118146
## Consequences
119147

@@ -134,9 +162,11 @@ flowchart LR
134162

135163
### Dependencies
136164

137-
- **Added**: drizzle-orm, drizzle-kit, @neondatabase/serverless
165+
- **Added**: drizzle-orm, drizzle-kit, pg, @vercel/functions
138166

139167
## Changelog
140168

141169
- **0.1 (2026-01-29)**: Initial version.
142170
- **0.2 (2026-01-30)**: Updated for current repo baseline (Bun, `src/` layout, CI).
171+
- **0.3 (2026-02-03)**: Updated connection method policy for Vercel Fluid compute (TCP pooling + `attachDatabasePool`).
172+
- **0.4 (2026-02-03)**: Linked to SPEC-0021 as the cross-cutting finalization spec.

docs/architecture/adr/ADR-0004-retrieval-upstash-vector-for-semantic-search.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
ADR: 0004
33
Title: Retrieval: Upstash Vector for semantic + hybrid search
44
Status: Accepted
5-
Version: 0.3
6-
Date: 2026-02-01
5+
Version: 0.4
6+
Date: 2026-02-03
77
Supersedes: []
88
Superseded-by: []
99
Related: [ADR-0003, ADR-0006, ADR-0024]
@@ -31,6 +31,10 @@ Prefer **HYBRID** vector indexes (dense + lexical) when provisioning new indexes
3131
to improve exact-token recall (important for code and identifiers), while still
3232
retaining semantic retrieval quality.
3333

34+
See [SPEC-0021](../spec/SPEC-0021-full-stack-finalization-fluid-compute-neon-upstash-ai-elements.md)
35+
for the cross-cutting “finalization” plan that ties Vector retrieval into
36+
ingestion, chat, search, and durable runs end-to-end.
37+
3438
## Context
3539

3640
System quality depends on grounding responses in uploaded sources, previously
@@ -122,9 +126,9 @@ flowchart LR
122126

123127
### Architecture Overview
124128

125-
Planned implementation module:
129+
Implementation module:
126130

127-
- `src/lib/upstash/vector.ts`: client + helper functions (namespace, upsert,
131+
- `src/lib/upstash/vector.server.ts`: client + helper functions (namespace, upsert,
128132
query, delete).
129133

130134
### Implementation Details
@@ -179,3 +183,4 @@ Planned implementation module:
179183
- **0.1 (2026-01-29)**: Initial version.
180184
- **0.2 (2026-01-30)**: Updated for current repo baseline (Bun, `src/` layout, CI).
181185
- **0.3 (2026-02-01)**: Updated for hybrid retrieval guidance.
186+
- **0.4 (2026-02-03)**: Updated file path references for server-only Vector client module.

docs/architecture/adr/ADR-0005-orchestration-upstash-qstash-for-durable-workflows.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
ADR: 0005
33
Title: Orchestration: Upstash QStash for durable workflows
44
Status: Accepted
5-
Version: 0.2
6-
Date: 2026-01-30
5+
Version: 0.3
6+
Date: 2026-02-03
77
Supersedes: []
88
Superseded-by: []
99
Related: [ADR-0013, ADR-0012]
@@ -21,6 +21,10 @@ Accepted — 2026-01-30.
2121

2222
Use QStash to execute multi-step runs durably and idempotently.
2323

24+
See [SPEC-0021](../spec/SPEC-0021-full-stack-finalization-fluid-compute-neon-upstash-ai-elements.md)
25+
for the cross-cutting “finalization” plan that ties QStash orchestration into
26+
run persistence, UI, and step execution patterns.
27+
2428
## Context
2529

2630
Full spec generation and research can exceed route execution limits. Durable orchestration ensures work completes even if the user closes the browser. QStash provides serverless-friendly HTTP-based queueing, signature verification, and retries.
@@ -146,3 +150,4 @@ flowchart LR
146150

147151
- **0.1 (2026-01-29)**: Initial version.
148152
- **0.2 (2026-01-30)**: Updated for current repo baseline (Bun, `src/` layout, CI).
153+
- **0.3 (2026-02-03)**: Linked to SPEC-0021 as the cross-cutting finalization spec.

docs/architecture/adr/ADR-0006-agent-runtime-ai-sdk-v6-toolloopagent-streaming-ui-responses.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
ADR: 0006
33
Title: Agent runtime: AI SDK v6 ToolLoopAgent + streaming UI responses
44
Status: Accepted
5-
Version: 0.2
6-
Date: 2026-01-30
5+
Version: 0.3
6+
Date: 2026-02-03
77
Supersedes: []
88
Superseded-by: []
99
Related: [ADR-0007, ADR-0011, ADR-0012]
@@ -22,6 +22,10 @@ Accepted — 2026-01-30.
2222

2323
Use AI SDK v6 agents for multi-step tool loops and streaming chat UX.
2424

25+
See [SPEC-0021](../spec/SPEC-0021-full-stack-finalization-fluid-compute-neon-upstash-ai-elements.md)
26+
for the cross-cutting “finalization” plan that ties agent streaming into the
27+
workspace UI, retrieval, caching, and durable orchestration.
28+
2529
## Context
2630

2731
The system requires multi-step reasoning and tool usage. AI SDK v6 provides ToolLoopAgent for iterative tool calls and createAgentUIStreamResponse for streaming message parts to the UI in Next.js Route Handlers.
@@ -141,3 +145,4 @@ flowchart LR
141145

142146
- **0.1 (2026-01-29)**: Initial version.
143147
- **0.2 (2026-01-30)**: Updated for current repo baseline (Bun, `src/` layout, CI).
148+
- **0.3 (2026-02-03)**: Linked to SPEC-0021 as the cross-cutting finalization spec.

docs/architecture/adr/ADR-0007-model-access-vercel-ai-gateway-exclusively.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
ADR: 0007
33
Title: Model access: Vercel AI Gateway exclusively
44
Status: Accepted
5-
Version: 0.2
6-
Date: 2026-01-30
5+
Version: 0.3
6+
Date: 2026-02-03
77
Supersedes: []
88
Superseded-by: []
99
Related: [ADR-0013, ADR-0021]
@@ -94,13 +94,17 @@ flowchart LR
9494

9595
### Architecture Overview
9696

97-
- `src/lib/ai/gateway.ts` exposes model factories and model listing for UI.
97+
- `src/lib/ai/gateway.server.ts` exposes AI Gateway provider wiring and model configuration.
9898
- `scripts/fetch-models.sh` fetches `/models` into `docs/ai-gateway-models.json`.
9999

100100
### Implementation Details
101101

102102
- Persist `model`, `provider`, `token_usage`, `latency_ms` in run steps.
103103
- Provide run-level budget checks before expensive steps.
104+
- Default model IDs are config-driven via env vars (see `docs/ops/env.md` and
105+
SPEC-0021):
106+
- `AI_GATEWAY_CHAT_MODEL` (default: `xai/grok-4.1-fast-reasoning`)
107+
- `AI_GATEWAY_EMBEDDING_MODEL` (default: `alibaba/qwen3-embedding-4b`)
104108

105109
## Testing
106110

@@ -138,3 +142,4 @@ flowchart LR
138142

139143
- **0.1 (2026-01-29)**: Initial version.
140144
- **0.2 (2026-01-30)**: Updated for current repo baseline (Bun, `src/` layout, CI).
145+
- **0.3 (2026-02-03)**: Updated file path references and recorded final default model IDs (SPEC-0021).

docs/architecture/adr/ADR-0009-file-storage-vercel-blob-for-uploads-originals.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ flowchart LR
9999
### Implementation Details
100100

101101
- `src/app/api/upload/route.ts`: streams to Blob.
102+
- Upload processing runs per-file work in parallel; async ingestion enqueues a
103+
QStash job per file with deduplication ids and labels.
104+
([QStash deduplication](https://upstash.com/docs/qstash/features/deduplication),
105+
[QStash publish API](https://upstash.com/docs/qstash/api-reference/messages/publish-a-message))
102106
- `src/lib/blob/client.ts`: wrapper with typed metadata.
103107
- Persist `blobUrl`, `sha256`, `sizeBytes`, `mimeType`.
104108

0 commit comments

Comments
 (0)