feat(#2): Implement PostgreSQL 17 + pgvector database schema

Establishes multi-tenant database layer with vector similarity search for AI-powered memory features. Includes Docker infrastructure, Prisma ORM integration, NestJS services, and shared types across the monorepo.

Key changes:
- Docker: PostgreSQL 17 + pgvector v0.7.4, Valkey cache
- Schema: 8 models (User, Workspace, Task, Event, Project, ActivityLog, MemoryEmbedding) with RLS preparation
- NestJS: PrismaModule, DatabaseModule, EmbeddingsService
- Shared: Type-safe enums, constants, and database types

Fixes #2

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jason Woltje
2026-01-28 16:06:34 -06:00
parent 355cf2124b
commit 99afde4f99
26 changed files with 1844 additions and 64 deletions

View File

@@ -0,0 +1,9 @@
/**
* Shared constants across the monorepo
*/
/**
* Embedding vector dimension for semantic memory
* Default: 1536 (OpenAI text-embedding-ada-002 dimension)
*/
export const EMBEDDING_DIMENSION = 1536;

View File

@@ -1,2 +1,3 @@
export * from "./types/index";
export * from "./utils/index";
export * from "./constants";

View File

@@ -0,0 +1,120 @@
/**
* Database entity type definitions
* These interfaces describe the shape of database entities
*/
import type { BaseEntity } from "./index";
import type {
TaskStatus,
TaskPriority,
ProjectStatus,
WorkspaceMemberRole,
ActivityAction,
EntityType,
} from "./enums";
/**
* User entity
*/
export interface User extends BaseEntity {
email: string;
name: string;
authProviderId: string | null;
preferences: Record<string, unknown>;
}
/**
* Workspace entity
*/
export interface Workspace extends BaseEntity {
name: string;
ownerId: string;
settings: Record<string, unknown>;
}
/**
* Workspace member entity (join table)
*/
export interface WorkspaceMember {
workspaceId: string;
userId: string;
role: WorkspaceMemberRole;
joinedAt: Date;
}
/**
* Task entity
*/
export interface Task extends BaseEntity {
workspaceId: string;
title: string;
description: string | null;
status: TaskStatus;
priority: TaskPriority;
dueDate: Date | null;
assigneeId: string | null;
creatorId: string;
projectId: string | null;
parentId: string | null;
sortOrder: number;
metadata: Record<string, unknown>;
completedAt: Date | null;
}
/**
* Event entity
*/
export interface Event extends BaseEntity {
workspaceId: string;
title: string;
description: string | null;
startTime: Date;
endTime: Date | null;
allDay: boolean;
location: string | null;
recurrence: Record<string, unknown> | null;
creatorId: string;
projectId: string | null;
metadata: Record<string, unknown>;
}
/**
* Project entity
*/
export interface Project extends BaseEntity {
workspaceId: string;
name: string;
description: string | null;
status: ProjectStatus;
startDate: Date | null;
endDate: Date | null;
creatorId: string;
color: string | null;
metadata: Record<string, unknown>;
}
/**
* Activity log entity
*/
export interface ActivityLog {
readonly id: string;
workspaceId: string;
userId: string;
action: ActivityAction;
entityType: EntityType;
entityId: string;
details: Record<string, unknown>;
readonly createdAt: Date;
}
/**
* Memory embedding entity
*/
export interface MemoryEmbedding extends BaseEntity {
workspaceId: string;
content: string;
embedding: number[] | null;
entityType: EntityType | null;
entityId: string | null;
metadata: Record<string, unknown>;
}

View File

@@ -0,0 +1,50 @@
/**
* Shared enum types that mirror Prisma schema enums
* These are used across the monorepo for type safety
*/
export enum TaskStatus {
NOT_STARTED = "NOT_STARTED",
IN_PROGRESS = "IN_PROGRESS",
PAUSED = "PAUSED",
COMPLETED = "COMPLETED",
ARCHIVED = "ARCHIVED",
}
export enum TaskPriority {
LOW = "LOW",
MEDIUM = "MEDIUM",
HIGH = "HIGH",
}
export enum ProjectStatus {
PLANNING = "PLANNING",
ACTIVE = "ACTIVE",
PAUSED = "PAUSED",
COMPLETED = "COMPLETED",
ARCHIVED = "ARCHIVED",
}
export enum WorkspaceMemberRole {
OWNER = "OWNER",
ADMIN = "ADMIN",
MEMBER = "MEMBER",
GUEST = "GUEST",
}
export enum ActivityAction {
CREATED = "CREATED",
UPDATED = "UPDATED",
DELETED = "DELETED",
COMPLETED = "COMPLETED",
ASSIGNED = "ASSIGNED",
COMMENTED = "COMMENTED",
}
export enum EntityType {
TASK = "TASK",
EVENT = "EVENT",
PROJECT = "PROJECT",
WORKSPACE = "WORKSPACE",
USER = "USER",
}

View File

@@ -119,3 +119,9 @@ export interface HealthStatus {
}
>;
}
// Export database enums
export * from "./enums";
// Export database entity types
export * from "./database.types";