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
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { getAuthUser, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { createAdminClient } from '@/lib/pocketbase';
import { emitEvent, EVENTS } from '@/lib/events/event-bus';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
// POST /api/analytics/vitals — Receive Web Vitals metrics
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import NextAuth from 'next-auth';
import { authOptions } from '@/lib/auth-config';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { getAuthUser } from '@/lib/auth';
@@ -0,0 +1,55 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { db, users } from '@project-e/db';
import { eq } from 'drizzle-orm';
// POST /api/auth/passkey/login — Verify passkey login
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { credentialId, signature, authenticatorData, clientDataJSON } = body;
if (!credentialId || !signature) {
return NextResponse.json(
{ error: { code: 'VALIDATION_ERROR', message: 'credentialId and signature are required' } },
{ status: 400 }
);
}
// Find user by credential ID
const [user] = await db
.select()
.from(users)
.where(eq(users.passkeyCredentialId, credentialId))
.limit(1);
if (!user) {
return NextResponse.json(
{ error: { code: 'UNAUTHORIZED', message: 'Passkey not found' } },
{ status: 401 }
);
}
// In production, verify the WebAuthn assertion here using SimpleWebAuthn
// For now, we accept the passkey and return the user info
// The actual verification will be implemented with @simplewebauthn/server
return NextResponse.json({
user: {
id: user.id,
email: user.email,
name: user.name,
},
});
} catch (error) {
console.error('[passkey/login] error:', error);
return NextResponse.json(
{ error: { code: 'INTERNAL_ERROR', message: 'Failed to verify passkey' } },
{ status: 500 }
);
}
}
@@ -0,0 +1,49 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { getAuthUser } from '@/lib/auth';
import { db, users } from '@project-e/db';
import { eq } from 'drizzle-orm';
// POST /api/auth/passkey/register — Start passkey registration
export async function POST(request: NextRequest) {
try {
const user = await getAuthUser(request);
if (!user) {
return NextResponse.json(
{ error: { code: 'UNAUTHORIZED', message: 'Not authenticated' } },
{ status: 401 }
);
}
const body = await request.json();
const { credentialId, publicKey, counter } = body;
if (!credentialId || !publicKey) {
return NextResponse.json(
{ error: { code: 'VALIDATION_ERROR', message: 'credentialId and publicKey are required' } },
{ status: 400 }
);
}
await db
.update(users)
.set({
passkeyCredentialId: credentialId,
passkeyPublicKey: publicKey,
passkeyCounter: counter ?? 0,
})
.where(eq(users.id, user.id));
return NextResponse.json({ success: true });
} catch (error) {
console.error('[passkey/register] error:', error);
return NextResponse.json(
{ error: { code: 'INTERNAL_ERROR', message: 'Failed to register passkey' } },
{ status: 500 }
);
}
}
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { getHabitStreaks } from '@/lib/services/habit-service';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextResponse } from 'next/server';
export async function GET() {
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
import { createMcpServer } from '@/lib/mcp/server';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { getBacklinks } from '@/lib/services/note-service';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { getNoteGraph } from '@/lib/services/note-service';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { computeProjectProgress } from '@/lib/services/project-service';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+21 -24
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest } from 'next/server';
import { getAuthUser } from '@/lib/auth';
import postgres from 'postgres';
@@ -5,17 +10,8 @@ import postgres from 'postgres';
export const dynamic = 'force-dynamic';
export const maxDuration = 300; // 5 minutes
const DEFAULT_COLLECTIONS = [
'tasks',
'habits',
'projects',
'notes',
'reports',
'milestones',
'notifications',
];
// GET /api/realtime — Multiplexed SSE endpoint backed by PostgreSQL LISTEN/NOTIFY.
// GET /api/realtime — SSE endpoint backed by PostgreSQL LISTEN/NOTIFY.
// Supports v2 entities: task, habit, project, note, domain, tag, section, habit_completion, activity
export async function GET(request: NextRequest) {
const user = await getAuthUser(request);
if (!user) {
@@ -25,16 +21,8 @@ export async function GET(request: NextRequest) {
});
}
// Parse subscription preferences from query params
const { searchParams } = new URL(request.url);
const collectionsParam = searchParams.get('collections') || '';
const collections = collectionsParam
.split(',')
.map((c) => c.trim())
.filter(Boolean);
const subscribedCollections =
collections.length > 0 ? collections : DEFAULT_COLLECTIONS;
const workspaceId = searchParams.get('workspace_id');
const encoder = new TextEncoder();
const listener = postgres(process.env.DATABASE_URL!, { max: 1 });
@@ -46,16 +34,25 @@ export async function GET(request: NextRequest) {
// Send connected event
controller.enqueue(
encoder.encode(
`data: ${JSON.stringify({ type: 'connected', collections: subscribedCollections })}\n\n`
`data: ${JSON.stringify({ type: 'connected', workspace_id: workspaceId })}\n\n`
)
);
const subscription = await listener.listen('project_e_events', (payload) => {
try {
const event = JSON.parse(payload) as { collection?: string };
if (!event.collection || subscribedCollections.includes(event.collection)) {
controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}\n\n`));
const event = JSON.parse(payload) as {
type: string;
action: string;
id: string;
workspace_id?: string;
};
// Filter by workspace_id if specified
if (workspaceId && event.workspace_id !== workspaceId) {
return;
}
controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}\n\n`));
} catch {
// Ignore malformed database notifications and closed streams.
}
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';
+5
View File
@@ -1,3 +1,8 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth, createErrorResponse } from '@/lib/auth';
import { createPocketBaseClient } from '@/lib/pocketbase';