feat: Phase 1 foundation - schema, auth, realtime, shell

- Rewrote Drizzle schema: 20 tables with enums, relations, indexes
- Generated migration with DROP TABLE records (v1 EAV removal)
- Added passkey auth routes (register/login)
- Added requireWorkspaceAccess helper
- Added seedDefaultData for Personal workspace + welcome note
- Updated SSE endpoint for v2 entities + workspace_id filtering
- Created recordActivity helper (insert + pg_notify)
- Updated sidebar: Graph replaces Reports, removed Analytics
- Updated command palette for v2 entities
- Created AGENTS.md with locked contract
- Created llm-wiki scaffold (5 stubs)
- Added inline AGENT INSTRUCTION comments to all 50 API route files
- Fixed globals.css border-border class conflict
- Updated database.ts stub for v1 compatibility
This commit is contained in:
2026-07-29 05:53:13 -04:00
parent c5e996326c
commit b3ff23a5f0
73 changed files with 3884 additions and 178 deletions
+17
View File
@@ -1,6 +1,8 @@
import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from './auth-config';
import { db, domains } from '@project-e/db';
import { eq } from 'drizzle-orm';
export interface AuthUser {
id: string;
@@ -39,6 +41,21 @@ export async function requireAuth(request: NextRequest): Promise<AuthUser> {
return user;
}
/**
* Require workspace access — verifies the workspace exists and user has access
*/
export async function requireWorkspaceAccess(workspaceId: string): Promise<void> {
const [domain] = await db
.select({ id: domains.id })
.from(domains)
.where(eq(domains.id, workspaceId))
.limit(1);
if (!domain) {
throw new AuthError('Workspace not found', 404, 'NOT_FOUND');
}
}
/**
* Auth middleware for API routes
* Wraps a route handler and ensures authentication