Initial commit: Clean DSS implementation

Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm

Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)

Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability

Migration completed: $(date)
🤖 Clean migration with full functionality preserved
This commit is contained in:
Digital Production Factory
2025-12-09 18:45:48 -03:00
commit 276ed71f31
884 changed files with 373737 additions and 0 deletions

View File

@@ -0,0 +1,250 @@
/**
* project-store.js
* Project configuration store
* Manages project list, current project selection, and project metadata
* MVP3: Integrates with API backend while maintaining localStorage fallback
*/
import apiClient from '../services/api-client.js';
export class ProjectStore {
constructor() {
// Load projects from localStorage (fallback for MVP2)
const stored = localStorage.getItem('projects_list');
this.projects = stored ? JSON.parse(stored) : this.getDefaultProjects();
// Load current project selection
this.currentProjectId = localStorage.getItem('current_project_id') || (this.projects.length > 0 ? this.projects[0].id : null);
this.listeners = new Set();
this.isLoading = false;
this.hasLoadedFromAPI = false;
// Try to load from API on initialization
this.syncWithAPI();
}
async syncWithAPI() {
try {
const projects = await apiClient.getProjects();
this.projects = projects;
this.hasLoadedFromAPI = true;
this.persist();
this.notifyListeners();
} catch (error) {
console.warn('[ProjectStore] Failed to sync with API, using localStorage:', error);
// Continue using localStorage data
}
}
getDefaultProjects() {
return [
{
id: 'DEFAULT-DESIGN-SYSTEM',
name: 'Default Design System',
skinSelected: 'default',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
}
];
}
/**
* Get all projects
* @returns {Array} Projects array
*/
getProjects() {
return [...this.projects];
}
/**
* Get current project
* @returns {Object|null} Current project or null
*/
getCurrentProject() {
return this.projects.find(p => p.id === this.currentProjectId) || null;
}
/**
* Get project by ID
* @param {string} id - Project ID
* @returns {Object|null} Project or null
*/
getProject(id) {
return this.projects.find(p => p.id === id) || null;
}
/**
* Create new project
* @param {Object} projectData - {name, key, description, figmaFileKey, jiraProjectKey, storybookUrl}
* @returns {Object} Created project
*/
async createProject(projectData) {
try {
// Try API first if authenticated
if (apiClient.accessToken) {
const project = await apiClient.createProject(projectData);
this.projects.push(project);
this.persist();
this.notifyListeners();
return project;
}
} catch (error) {
console.warn('[ProjectStore] API creation failed, using localStorage:', error);
}
// Fallback to localStorage
const now = new Date().toISOString();
const project = {
id: projectData.id || `PROJECT-${Date.now()}`,
name: projectData.name || 'Untitled Project',
key: projectData.key || `KEY-${Date.now()}`,
description: projectData.description || '',
createdAt: now,
updatedAt: now,
...projectData
};
this.projects.push(project);
this.persist();
this.notifyListeners();
return project;
}
/**
* Update project
* @param {string} id - Project ID
* @param {Object} updates - Partial project updates
* @returns {Object|null} Updated project or null
*/
async updateProject(id, updates) {
const project = this.projects.find(p => p.id === id);
if (!project) return null;
try {
// Try API first if authenticated
if (apiClient.accessToken) {
const updated = await apiClient.updateProject(id, updates);
const index = this.projects.findIndex(p => p.id === id);
if (index !== -1) {
this.projects[index] = updated;
}
this.persist();
this.notifyListeners();
return updated;
}
} catch (error) {
console.warn('[ProjectStore] API update failed, using localStorage:', error);
}
// Fallback to localStorage
Object.assign(project, updates, {
updatedAt: new Date().toISOString()
});
this.persist();
this.notifyListeners();
return project;
}
/**
* Delete project
* @param {string} id - Project ID
* @returns {boolean} Success
*/
async deleteProject(id) {
try {
// Try API first if authenticated
if (apiClient.accessToken) {
await apiClient.deleteProject(id);
}
} catch (error) {
console.warn('[ProjectStore] API deletion failed, using localStorage:', error);
}
const index = this.projects.findIndex(p => p.id === id);
if (index === -1) return false;
this.projects.splice(index, 1);
// If deleted project was selected, select first available
if (this.currentProjectId === id) {
this.currentProjectId = this.projects.length > 0 ? this.projects[0].id : null;
localStorage.setItem('current_project_id', this.currentProjectId || '');
}
this.persist();
this.notifyListeners();
return true;
}
/**
* Select/switch to different project
* @param {string} id - Project ID
* @returns {Object|null} Selected project or null
*/
selectProject(id) {
const project = this.projects.find(p => p.id === id);
if (!project) return null;
this.currentProjectId = id;
localStorage.setItem('current_project_id', id);
this.notifyListeners();
return project;
}
/**
* Update selected skin for current project
* @param {string} skin - Skin name
* @returns {Object|null} Updated project
*/
setSkinForCurrentProject(skin) {
if (!this.currentProjectId) return null;
return this.updateProject(this.currentProjectId, { skinSelected: skin });
}
/**
* Persist to localStorage
*/
persist() {
localStorage.setItem('projects_list', JSON.stringify(this.projects));
}
/**
* Subscribe to changes
* @param {Function} callback - Called on state changes
* @returns {Function} Unsubscribe function
*/
subscribe(callback) {
this.listeners.add(callback);
return () => this.listeners.delete(callback);
}
notifyListeners() {
this.listeners.forEach(listener => listener({
projects: this.getProjects(),
currentProject: this.getCurrentProject()
}));
}
/**
* Reset to default project
*/
reset() {
localStorage.removeItem('projects_list');
localStorage.removeItem('current_project_id');
this.projects = this.getDefaultProjects();
this.currentProjectId = this.projects[0].id;
this.notifyListeners();
}
}
// Singleton instance
let projectStoreInstance = null;
export function useProjectStore() {
if (!projectStoreInstance) {
projectStoreInstance = new ProjectStore();
}
return projectStoreInstance;
}