@bernierllc/content-project-manager
v0.3.0
Published
Service for managing relationships between content items, projects, and external sources
Readme
@bernierllc/content-project-manager
Service for managing relationships between content items, projects, and external sources.
Features
- Project Management: Create, update, delete, and query projects
- Content Relationships: Link content items together with typed relationships
- Project-Content Linking: Associate content with projects with optional roles
- Relationship Graphs: Build and traverse content relationship graphs
- Event Emitting: Subscribe to project and content lifecycle events
- Database Agnostic: Works with any SQL database via IDatabaseAdapter
- Optional NeverHub Integration: Auto-detects and integrates with NeverHub service discovery
Installation
npm install @bernierllc/content-project-managerUsage
Basic Setup
import { ContentProjectManager } from '@bernierllc/content-project-manager';
import { PostgreSQLAdapter } from '@bernierllc/database-adapter-postgresql';
import { createLogger } from '@bernierllc/logger';
const database = new PostgreSQLAdapter({
host: 'localhost',
port: 5432,
database: 'mydb',
user: 'user',
password: 'password',
});
const logger = createLogger({ level: 'info' });
const manager = new ContentProjectManager({
database,
logger,
});
await manager.initialize();Project Management
// Create a project
const result = await manager.createProject({
name: 'Q1 Marketing Campaign',
description: 'Content for Q1 2025 marketing initiative',
status: 'active',
metadata: { budget: 50000, team: 'marketing' },
});
// Get a project
const project = await manager.getProject(result.data.id);
// Update a project
await manager.updateProject(result.data.id, {
status: 'completed',
metadata: { actualBudget: 48000 },
});
// Delete a project
await manager.deleteProject(result.data.id);Content-Project Linking
// Add content to a project
await manager.addContentToProject(
'project-123',
'content-456',
{ role: 'featured' }
);
// Get all content in a project
const content = await manager.getProjectContent('project-123', {
role: 'featured',
limit: 10,
});
// Remove content from project
await manager.removeContentFromProject('project-123', 'content-456');Content Relationships
// Create a relationship
await manager.createRelationship({
sourceId: 'blog-post-1',
targetId: 'social-post-1',
type: 'derived-from',
metadata: { platform: 'twitter' },
});
// Get relationships for content
const relationships = await manager.getRelationships('blog-post-1', {
type: 'derived-from',
direction: 'source',
});
// Link blog to multiple social posts
await manager.linkBlogToSocialPosts('blog-post-1', [
'twitter-post-1',
'linkedin-post-1',
'facebook-post-1',
]);Relationship Graphs
// Build a content graph
const graph = await manager.getContentGraph('root-content-id', 3);
// Graph structure:
// {
// id: 'root-content-id',
// relationships: [...],
// children: [
// { id: 'child-1', relationships: [...], children: [...] },
// { id: 'child-2', relationships: [...] }
// ]
// }Event Subscriptions
manager.on('project:created', (data) => {
console.log('New project created:', data.project);
});
manager.on('project:updated', (data) => {
console.log('Project updated:', data.project);
});
manager.on('project:deleted', (data) => {
console.log('Project deleted:', data.projectId);
});
manager.on('content:added', (data) => {
console.log('Content added to project:', data);
});
manager.on('content:removed', (data) => {
console.log('Content removed from project:', data);
});
manager.on('relationship:created', (data) => {
console.log('Relationship created:', data.relationship);
});API Reference
ContentProjectManager
Constructor
constructor(config: ServiceConfig)config.database(required): IDatabaseAdapter instanceconfig.logger(optional): Logger instance
Methods
initialize(): Promise<void>
Initialize the service and create database schema.
createProject(options: CreateProjectOptions): Promise<IServiceResult<Project>>
Create a new project.
getProject(id: string): Promise<IServiceResult<Project>>
Get project by ID.
updateProject(id: string, updates: UpdateProjectOptions): Promise<IServiceResult<Project>>
Update an existing project.
deleteProject(id: string): Promise<IServiceResult<void>>
Delete a project.
addContentToProject(projectId: string, contentId: string, metadata?: { role?: string }): Promise<IServiceResult<ContentProjectLink>>
Add content to a project.
removeContentFromProject(projectId: string, contentId: string): Promise<IServiceResult<void>>
Remove content from a project.
getProjectContent(projectId: string, filters?: ProjectContentFilters): Promise<IServiceResult<ContentProjectLink[]>>
Get all content in a project with optional filters.
createRelationship(options: CreateRelationshipOptions): Promise<IServiceResult<ContentRelationship>>
Create a relationship between two content items.
getRelationships(contentId: string, options?: GetRelationshipsOptions): Promise<IServiceResult<ContentRelationship[]>>
Get relationships for a content item.
linkBlogToSocialPosts(blogId: string, socialPostIds: string[]): Promise<IServiceResult<ContentRelationship[]>>
Convenience method to link a blog post to multiple social media posts.
getContentGraph(rootId: string, depth?: number): Promise<IServiceResult<ContentGraphNode>>
Build a relationship graph starting from a root content item.
close(): Promise<void>
Close the service and clean up resources.
Database Schema
The service creates three tables:
projects
CREATE TABLE projects (
id UUID PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
status VARCHAR(50) DEFAULT 'active',
metadata JSONB,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);content_projects
CREATE TABLE content_projects (
project_id UUID REFERENCES projects(id) ON DELETE CASCADE,
content_id UUID NOT NULL,
role VARCHAR(100),
added_at TIMESTAMP DEFAULT NOW(),
PRIMARY KEY (project_id, content_id)
);content_relationships
CREATE TABLE content_relationships (
id UUID PRIMARY KEY,
source_id UUID NOT NULL,
target_id UUID NOT NULL,
relationship_type VARCHAR(100) NOT NULL,
metadata JSONB,
created_at TIMESTAMP DEFAULT NOW()
);Events
initialized- Emitted when service is initializedproject:created- Emitted when a project is createdproject:updated- Emitted when a project is updatedproject:deleted- Emitted when a project is deletedcontent:added- Emitted when content is added to a projectcontent:removed- Emitted when content is removed from a projectrelationship:created- Emitted when a relationship is createdclosed- Emitted when service is closed
License
Copyright (c) 2025 Bernier LLC
This file is licensed to the client under a limited-use license.
