@ebowwa/crm 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -0
- package/dist/cli/commands/activities.d.ts +11 -0
- package/dist/cli/commands/activities.d.ts.map +1 -0
- package/dist/cli/commands/activities.js +427 -0
- package/dist/cli/commands/activities.js.map +1 -0
- package/dist/cli/commands/contacts.d.ts +11 -0
- package/dist/cli/commands/contacts.d.ts.map +1 -0
- package/dist/cli/commands/contacts.js +458 -0
- package/dist/cli/commands/contacts.js.map +1 -0
- package/dist/cli/commands/deals.d.ts +11 -0
- package/dist/cli/commands/deals.d.ts.map +1 -0
- package/dist/cli/commands/deals.js +498 -0
- package/dist/cli/commands/deals.js.map +1 -0
- package/dist/cli/commands/media.d.ts +11 -0
- package/dist/cli/commands/media.d.ts.map +1 -0
- package/dist/cli/commands/media.js +417 -0
- package/dist/cli/commands/media.js.map +1 -0
- package/dist/cli/commands/search.d.ts +11 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +346 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +173 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/repl.d.ts +15 -0
- package/dist/cli/repl.d.ts.map +1 -0
- package/dist/cli/repl.js +318 -0
- package/dist/cli/repl.js.map +1 -0
- package/dist/cli/utils/config.d.ts +91 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +212 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/output.d.ts +136 -0
- package/dist/cli/utils/output.d.ts.map +1 -0
- package/dist/cli/utils/output.js +323 -0
- package/dist/cli/utils/output.js.map +1 -0
- package/dist/cli/utils/prompt.d.ts +81 -0
- package/dist/cli/utils/prompt.d.ts.map +1 -0
- package/dist/cli/utils/prompt.js +341 -0
- package/dist/cli/utils/prompt.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +32 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/schemas.d.ts +3050 -0
- package/dist/core/schemas.d.ts.map +1 -0
- package/dist/core/schemas.js +667 -0
- package/dist/core/schemas.js.map +1 -0
- package/dist/core/types.d.ts +597 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +8 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +14 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +18 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/storage/client.d.ts +109 -0
- package/dist/mcp/storage/client.d.ts.map +1 -0
- package/dist/mcp/storage/client.js +355 -0
- package/dist/mcp/storage/client.js.map +1 -0
- package/dist/mcp/storage/index.d.ts +7 -0
- package/dist/mcp/storage/index.d.ts.map +1 -0
- package/dist/mcp/storage/index.js +6 -0
- package/dist/mcp/storage/index.js.map +1 -0
- package/dist/mcp/storage/types.d.ts +44 -0
- package/dist/mcp/storage/types.d.ts.map +1 -0
- package/dist/mcp/storage/types.js +35 -0
- package/dist/mcp/storage/types.js.map +1 -0
- package/dist/mcp/tools/definitions.d.ts +16 -0
- package/dist/mcp/tools/definitions.d.ts.map +1 -0
- package/dist/mcp/tools/definitions.js +914 -0
- package/dist/mcp/tools/definitions.js.map +1 -0
- package/dist/mcp/tools/handlers.d.ts +50 -0
- package/dist/mcp/tools/handlers.d.ts.map +1 -0
- package/dist/mcp/tools/handlers.js +760 -0
- package/dist/mcp/tools/handlers.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +7 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +6 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/types.d.ts +314 -0
- package/dist/mcp/tools/types.d.ts.map +1 -0
- package/dist/mcp/tools/types.js +5 -0
- package/dist/mcp/tools/types.js.map +1 -0
- package/dist/mcp/transports/stdio.d.ts +27 -0
- package/dist/mcp/transports/stdio.d.ts.map +1 -0
- package/dist/mcp/transports/stdio.js +237 -0
- package/dist/mcp/transports/stdio.js.map +1 -0
- package/dist/telemetry/index.d.ts +58 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +109 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/logger.d.ts +116 -0
- package/dist/telemetry/logger.d.ts.map +1 -0
- package/dist/telemetry/logger.js +256 -0
- package/dist/telemetry/logger.js.map +1 -0
- package/dist/telemetry/metrics.d.ts +115 -0
- package/dist/telemetry/metrics.d.ts.map +1 -0
- package/dist/telemetry/metrics.js +292 -0
- package/dist/telemetry/metrics.js.map +1 -0
- package/dist/telemetry/tracer.d.ts +227 -0
- package/dist/telemetry/tracer.d.ts.map +1 -0
- package/dist/telemetry/tracer.js +355 -0
- package/dist/telemetry/tracer.js.map +1 -0
- package/dist/web/app.d.ts +2 -0
- package/dist/web/app.d.ts.map +1 -0
- package/dist/web/app.js +115 -0
- package/dist/web/app.js.map +1 -0
- package/dist/web/components/ContactList.d.ts +3 -0
- package/dist/web/components/ContactList.d.ts.map +1 -0
- package/dist/web/components/ContactList.js +262 -0
- package/dist/web/components/ContactList.js.map +1 -0
- package/dist/web/components/Dashboard.d.ts +3 -0
- package/dist/web/components/Dashboard.d.ts.map +1 -0
- package/dist/web/components/Dashboard.js +158 -0
- package/dist/web/components/Dashboard.js.map +1 -0
- package/dist/web/components/DealPipeline.d.ts +3 -0
- package/dist/web/components/DealPipeline.d.ts.map +1 -0
- package/dist/web/components/DealPipeline.js +306 -0
- package/dist/web/components/DealPipeline.js.map +1 -0
- package/dist/web/index.d.ts +2 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +269 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/types.d.ts +75 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/types.js +3 -0
- package/dist/web/types.js.map +1 -0
- package/native/index.d.ts +571 -0
- package/native/index.js +687 -0
- package/package.json +105 -0
- package/src/cli/commands/activities.ts +543 -0
- package/src/cli/commands/contacts.ts +563 -0
- package/src/cli/commands/deals.ts +637 -0
- package/src/cli/commands/media.ts +521 -0
- package/src/cli/commands/search.ts +426 -0
- package/src/cli/index.ts +203 -0
- package/src/cli/repl.ts +379 -0
- package/src/cli/utils/config.ts +299 -0
- package/src/cli/utils/output.ts +386 -0
- package/src/cli/utils/prompt.ts +444 -0
- package/src/cli.ts +11 -0
- package/src/core/index.ts +184 -0
- package/src/core/schemas.ts +770 -0
- package/src/core/types.ts +969 -0
- package/src/index.ts +8 -0
- package/src/mcp/index.ts +17 -0
- package/src/mcp/server.ts +26 -0
- package/src/mcp/storage/client.ts +408 -0
- package/src/mcp/storage/index.ts +7 -0
- package/src/mcp/storage/types.ts +72 -0
- package/src/mcp/tools/definitions.ts +961 -0
- package/src/mcp/tools/handlers.ts +805 -0
- package/src/mcp/tools/index.ts +7 -0
- package/src/mcp/tools/types.ts +390 -0
- package/src/mcp/transports/stdio.ts +225 -0
- package/src/telemetry/index.ts +131 -0
- package/src/telemetry/logger.ts +318 -0
- package/src/telemetry/metrics.ts +393 -0
- package/src/telemetry/tracer.ts +487 -0
- package/src/web/api/activities.ts +41 -0
- package/src/web/api/contacts.ts +114 -0
- package/src/web/api/deals.ts +108 -0
- package/src/web/api/media.ts +98 -0
- package/src/web/app.tsx +143 -0
- package/src/web/components/ActivityFeed.tsx +195 -0
- package/src/web/components/ContactList.tsx +340 -0
- package/src/web/components/Dashboard.tsx +214 -0
- package/src/web/components/DealPipeline.tsx +405 -0
- package/src/web/components/MediaGallery.tsx +334 -0
- package/src/web/index.html +14 -0
- package/src/web/index.ts +326 -0
- package/src/web/styles/main.css +180 -0
- package/src/web/types.ts +311 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/* CRM Custom Styles */
|
|
2
|
+
|
|
3
|
+
/* Base */
|
|
4
|
+
:root {
|
|
5
|
+
--color-primary: #6366f1;
|
|
6
|
+
--color-secondary: #8b5cf6;
|
|
7
|
+
--color-accent: #06b6d4;
|
|
8
|
+
--color-success: #10b981;
|
|
9
|
+
--color-warning: #f59e0b;
|
|
10
|
+
--color-danger: #ef4444;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Scrollbar */
|
|
14
|
+
::-webkit-scrollbar {
|
|
15
|
+
width: 8px;
|
|
16
|
+
height: 8px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
::-webkit-scrollbar-track {
|
|
20
|
+
background: #1f2937;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
::-webkit-scrollbar-thumb {
|
|
24
|
+
background: #4b5563;
|
|
25
|
+
border-radius: 4px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
::-webkit-scrollbar-thumb:hover {
|
|
29
|
+
background: #6b7280;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* Animations */
|
|
33
|
+
@keyframes fadeIn {
|
|
34
|
+
from { opacity: 0; transform: translateY(-10px); }
|
|
35
|
+
to { opacity: 1; transform: translateY(0); }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@keyframes slideIn {
|
|
39
|
+
from { opacity: 0; transform: translateX(-20px); }
|
|
40
|
+
to { opacity: 1; transform: translateX(0); }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@keyframes pulse-glow {
|
|
44
|
+
0%, 100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.4); }
|
|
45
|
+
50% { box-shadow: 0 0 0 10px rgba(99, 102, 241, 0); }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.animate-fade-in {
|
|
49
|
+
animation: fadeIn 0.3s ease-out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.animate-slide-in {
|
|
53
|
+
animation: slideIn 0.3s ease-out;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.animate-pulse-glow {
|
|
57
|
+
animation: pulse-glow 2s infinite;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Cards */
|
|
61
|
+
.crm-card {
|
|
62
|
+
@apply bg-gray-800 rounded-xl border border-gray-700 p-4 transition-all duration-200;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.crm-card:hover {
|
|
66
|
+
@apply border-gray-600 shadow-lg;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Pipeline */
|
|
70
|
+
.pipeline-column {
|
|
71
|
+
@apply bg-gray-800/50 rounded-lg p-3 min-h-[400px];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.pipeline-card {
|
|
75
|
+
@apply bg-gray-800 rounded-lg border border-gray-700 p-3 mb-2 cursor-pointer transition-all;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.pipeline-card:hover {
|
|
79
|
+
@apply border-indigo-500 shadow-md transform: translateY(-2px);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.pipeline-card.dragging {
|
|
83
|
+
@apply opacity-50 border-indigo-400;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Activity Feed */
|
|
87
|
+
.activity-item {
|
|
88
|
+
@apply flex items-start gap-3 p-3 rounded-lg hover:bg-gray-800/50 transition-colors;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.activity-dot {
|
|
92
|
+
@apply w-2 h-2 rounded-full mt-2;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Media Gallery */
|
|
96
|
+
.media-grid {
|
|
97
|
+
@apply grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.media-item {
|
|
101
|
+
@apply aspect-square bg-gray-800 rounded-lg overflow-hidden border border-gray-700 hover:border-indigo-500 transition-all cursor-pointer;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.media-item:hover {
|
|
105
|
+
@apply transform scale-105 shadow-lg;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Forms */
|
|
109
|
+
.crm-input {
|
|
110
|
+
@apply w-full bg-gray-800 border border-gray-700 rounded-lg px-4 py-2 text-gray-100 placeholder-gray-500 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 outline-none transition-all;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.crm-btn {
|
|
114
|
+
@apply px-4 py-2 rounded-lg font-medium transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.crm-btn-primary {
|
|
118
|
+
@apply bg-indigo-600 hover:bg-indigo-500 text-white;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.crm-btn-secondary {
|
|
122
|
+
@apply bg-gray-700 hover:bg-gray-600 text-gray-100;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.crm-btn-danger {
|
|
126
|
+
@apply bg-red-600 hover:bg-red-500 text-white;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Tags */
|
|
130
|
+
.crm-tag {
|
|
131
|
+
@apply inline-flex items-center px-2 py-1 rounded-full text-xs font-medium;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.crm-tag-success {
|
|
135
|
+
@apply bg-green-900/50 text-green-400;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.crm-tag-warning {
|
|
139
|
+
@apply bg-yellow-900/50 text-yellow-400;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.crm-tag-danger {
|
|
143
|
+
@apply bg-red-900/50 text-red-400;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.crm-tag-info {
|
|
147
|
+
@apply bg-blue-900/50 text-blue-400;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Modal */
|
|
151
|
+
.crm-modal-backdrop {
|
|
152
|
+
@apply fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.crm-modal {
|
|
156
|
+
@apply bg-gray-800 rounded-xl border border-gray-700 p-6 max-w-lg w-full mx-4 animate-fade-in;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* Toast */
|
|
160
|
+
.crm-toast {
|
|
161
|
+
@apply fixed bottom-4 right-4 bg-gray-800 border border-gray-700 rounded-lg px-4 py-3 shadow-lg animate-slide-in z-50;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* Status indicators */
|
|
165
|
+
.status-active {
|
|
166
|
+
@apply bg-green-500;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.status-inactive {
|
|
170
|
+
@apply bg-gray-500;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.status-pending {
|
|
174
|
+
@apply bg-yellow-500;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* Loading spinner */
|
|
178
|
+
.crm-spinner {
|
|
179
|
+
@apply w-6 h-6 border-2 border-gray-600 border-t-indigo-500 rounded-full animate-spin;
|
|
180
|
+
}
|
package/src/web/types.ts
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web API Types for CRM System
|
|
3
|
+
*
|
|
4
|
+
* Re-exports from core types and provides API-specific wrappers.
|
|
5
|
+
* These types align with src/core/types.ts to ensure contract integrity.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Re-export Core Types (Canonical Source of Truth)
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export type {
|
|
13
|
+
UUID,
|
|
14
|
+
Timestamp,
|
|
15
|
+
Metadata,
|
|
16
|
+
BaseEntity,
|
|
17
|
+
// Contact types
|
|
18
|
+
Contact,
|
|
19
|
+
PhoneNumber,
|
|
20
|
+
EmailAddress,
|
|
21
|
+
Address,
|
|
22
|
+
SocialProfile,
|
|
23
|
+
CustomField,
|
|
24
|
+
ContactSource,
|
|
25
|
+
ContactStatus,
|
|
26
|
+
// Deal types
|
|
27
|
+
Deal,
|
|
28
|
+
DealStage,
|
|
29
|
+
DealPriority,
|
|
30
|
+
Currency,
|
|
31
|
+
DealLineItem,
|
|
32
|
+
Competitor,
|
|
33
|
+
// Activity types
|
|
34
|
+
Activity,
|
|
35
|
+
ActivityType,
|
|
36
|
+
CallOutcome,
|
|
37
|
+
MeetingOutcome,
|
|
38
|
+
EmailStatus,
|
|
39
|
+
CallMetadata,
|
|
40
|
+
MeetingMetadata,
|
|
41
|
+
EmailMetadata,
|
|
42
|
+
TaskMetadata,
|
|
43
|
+
// Media types
|
|
44
|
+
Media,
|
|
45
|
+
MediaType,
|
|
46
|
+
MimeType,
|
|
47
|
+
ImageMetadata,
|
|
48
|
+
VideoMetadata,
|
|
49
|
+
AudioMetadata,
|
|
50
|
+
DocumentMetadata,
|
|
51
|
+
// Note types
|
|
52
|
+
Note,
|
|
53
|
+
NoteVisibility,
|
|
54
|
+
// Tag types
|
|
55
|
+
Tag,
|
|
56
|
+
TagCategory,
|
|
57
|
+
// Company types
|
|
58
|
+
Company,
|
|
59
|
+
CompanySize,
|
|
60
|
+
Industry,
|
|
61
|
+
// Pipeline types
|
|
62
|
+
Pipeline,
|
|
63
|
+
PipelineStage,
|
|
64
|
+
// Filter types
|
|
65
|
+
SortDirection,
|
|
66
|
+
SortOptions,
|
|
67
|
+
PaginationOptions,
|
|
68
|
+
PaginatedResponse as CorePaginatedResponse,
|
|
69
|
+
DateRange,
|
|
70
|
+
ContactFilter,
|
|
71
|
+
DealFilter,
|
|
72
|
+
ActivityFilter,
|
|
73
|
+
} from '../core/types.js';
|
|
74
|
+
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// API-Specific Types
|
|
77
|
+
// ============================================================================
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Flat contact representation for simple API use cases.
|
|
81
|
+
* Use this for backward compatibility with legacy API consumers.
|
|
82
|
+
* For full contact data, use Contact from core types.
|
|
83
|
+
*/
|
|
84
|
+
export interface FlatContact {
|
|
85
|
+
id: string;
|
|
86
|
+
name: string;
|
|
87
|
+
email: string; // Primary email (flattened from emails[0].email)
|
|
88
|
+
phone?: string; // Primary phone (flattened from phones[0].number)
|
|
89
|
+
company?: string;
|
|
90
|
+
title?: string;
|
|
91
|
+
status: 'lead' | 'prospect' | 'qualified' | 'customer' | 'churned' | 'archived';
|
|
92
|
+
tags: string[];
|
|
93
|
+
notes?: string;
|
|
94
|
+
createdAt: string;
|
|
95
|
+
updatedAt: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Flat deal representation for simple API use cases.
|
|
100
|
+
* Use this for backward compatibility with legacy API consumers.
|
|
101
|
+
* For full deal data, use Deal from core types.
|
|
102
|
+
*/
|
|
103
|
+
export interface FlatDeal {
|
|
104
|
+
id: string;
|
|
105
|
+
contactId: string;
|
|
106
|
+
title: string;
|
|
107
|
+
value: number;
|
|
108
|
+
currency: string;
|
|
109
|
+
stage: 'prospecting' | 'qualification' | 'needs_analysis' | 'proposal' | 'negotiation' | 'closed_won' | 'closed_lost';
|
|
110
|
+
probability: number;
|
|
111
|
+
expectedCloseDate?: string; // Maps to expectedClose in core Deal
|
|
112
|
+
description?: string; // Maps to notes in core Deal
|
|
113
|
+
createdAt: string;
|
|
114
|
+
updatedAt: string;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Flat activity representation for simple API use cases.
|
|
119
|
+
* Use this for backward compatibility with legacy API consumers.
|
|
120
|
+
* For full activity data, use Activity from core types.
|
|
121
|
+
*/
|
|
122
|
+
export interface FlatActivity {
|
|
123
|
+
id: string;
|
|
124
|
+
type: 'call' | 'email' | 'meeting' | 'task' | 'note' | 'sms' | 'video_call' | 'demo' | 'proposal_sent' | 'contract_sent' | 'follow_up' | 'social_media' | 'event' | 'other';
|
|
125
|
+
description: string;
|
|
126
|
+
contactId?: string;
|
|
127
|
+
dealId?: string;
|
|
128
|
+
userId: string; // Maps to createdBy in core Activity
|
|
129
|
+
timestamp: string;
|
|
130
|
+
metadata?: Record<string, unknown>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Flat media representation for simple API use cases.
|
|
135
|
+
*/
|
|
136
|
+
export interface FlatMedia {
|
|
137
|
+
id: string;
|
|
138
|
+
filename: string;
|
|
139
|
+
mimetype: string;
|
|
140
|
+
size: number;
|
|
141
|
+
url: string;
|
|
142
|
+
thumbnailUrl?: string;
|
|
143
|
+
contactId?: string;
|
|
144
|
+
dealId?: string;
|
|
145
|
+
uploadedBy: string;
|
|
146
|
+
uploadedAt: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// Dashboard Types
|
|
151
|
+
// ============================================================================
|
|
152
|
+
|
|
153
|
+
export interface DashboardStats {
|
|
154
|
+
totalContacts: number;
|
|
155
|
+
activeDeals: number;
|
|
156
|
+
pipelineValue: number;
|
|
157
|
+
wonThisMonth: number;
|
|
158
|
+
activitiesToday: number;
|
|
159
|
+
conversionRate: number;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ============================================================================
|
|
163
|
+
// WebSocket Types
|
|
164
|
+
// ============================================================================
|
|
165
|
+
|
|
166
|
+
export interface WSMessage {
|
|
167
|
+
type: 'connected' | 'activity' | 'deal_update' | 'contact_update' | 'media_upload';
|
|
168
|
+
payload?: unknown;
|
|
169
|
+
timestamp: string;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ============================================================================
|
|
173
|
+
// API Response Types
|
|
174
|
+
// ============================================================================
|
|
175
|
+
|
|
176
|
+
export interface APIResponse<T> {
|
|
177
|
+
success: boolean;
|
|
178
|
+
data?: T;
|
|
179
|
+
error?: string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Paginated response for web API.
|
|
184
|
+
* Note: Core types have CorePaginatedResponse with different field names.
|
|
185
|
+
*/
|
|
186
|
+
export interface PaginatedResponse<T> {
|
|
187
|
+
items: T[];
|
|
188
|
+
total: number;
|
|
189
|
+
page: number;
|
|
190
|
+
pageSize: number;
|
|
191
|
+
hasMore: boolean;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ============================================================================
|
|
195
|
+
// Type Conversion Utilities
|
|
196
|
+
// ============================================================================
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Convert a full Contact to a flat representation for legacy API compatibility.
|
|
200
|
+
*/
|
|
201
|
+
export function toFlatContact(contact: import('../core/types.js').Contact): FlatContact {
|
|
202
|
+
const primaryEmail = contact.emails.find(e => e.primary) || contact.emails[0];
|
|
203
|
+
const primaryPhone = contact.phones.find(p => p.primary) || contact.phones[0];
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
id: contact.id,
|
|
207
|
+
name: contact.name,
|
|
208
|
+
email: primaryEmail?.email || '',
|
|
209
|
+
phone: primaryPhone?.number,
|
|
210
|
+
company: contact.company,
|
|
211
|
+
title: contact.title,
|
|
212
|
+
status: contact.status,
|
|
213
|
+
tags: contact.tags,
|
|
214
|
+
notes: contact.preferences, // Map preferences to notes for flat view
|
|
215
|
+
createdAt: contact.createdAt,
|
|
216
|
+
updatedAt: contact.updatedAt,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Convert a flat contact input to a full Contact structure.
|
|
222
|
+
*/
|
|
223
|
+
export function fromFlatContactInput(input: Partial<FlatContact> & { name: string }): Partial<import('../core/types.js').Contact> {
|
|
224
|
+
return {
|
|
225
|
+
name: input.name,
|
|
226
|
+
firstName: input.name?.split(' ')[0],
|
|
227
|
+
lastName: input.name?.split(' ').slice(1).join(' '),
|
|
228
|
+
emails: input.email ? [{ email: input.email, type: 'personal', primary: true }] : [],
|
|
229
|
+
phones: input.phone ? [{ number: input.phone, type: 'mobile', primary: true }] : [],
|
|
230
|
+
company: input.company,
|
|
231
|
+
title: input.title,
|
|
232
|
+
status: input.status || 'lead',
|
|
233
|
+
tags: input.tags || [],
|
|
234
|
+
preferences: input.notes,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Convert a full Deal to a flat representation for legacy API compatibility.
|
|
240
|
+
*/
|
|
241
|
+
export function toFlatDeal(deal: import('../core/types.js').Deal): FlatDeal {
|
|
242
|
+
return {
|
|
243
|
+
id: deal.id,
|
|
244
|
+
contactId: deal.contactId,
|
|
245
|
+
title: deal.title,
|
|
246
|
+
value: deal.value,
|
|
247
|
+
currency: deal.currency,
|
|
248
|
+
stage: deal.stage,
|
|
249
|
+
probability: deal.probability,
|
|
250
|
+
expectedCloseDate: deal.expectedClose,
|
|
251
|
+
description: deal.notes,
|
|
252
|
+
createdAt: deal.createdAt,
|
|
253
|
+
updatedAt: deal.updatedAt,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Convert a flat deal input to a full Deal structure.
|
|
259
|
+
*/
|
|
260
|
+
export function fromFlatDealInput(input: Partial<FlatDeal> & { contactId: string; title: string; value: number }): Partial<import('../core/types.js').Deal> {
|
|
261
|
+
return {
|
|
262
|
+
contactId: input.contactId,
|
|
263
|
+
title: input.title,
|
|
264
|
+
value: input.value,
|
|
265
|
+
currency: input.currency || 'USD',
|
|
266
|
+
stage: input.stage || 'prospecting',
|
|
267
|
+
probability: input.probability || 10,
|
|
268
|
+
expectedClose: input.expectedCloseDate || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
269
|
+
notes: input.description || '',
|
|
270
|
+
totalValue: input.value,
|
|
271
|
+
lineItems: [],
|
|
272
|
+
competitors: [],
|
|
273
|
+
tags: [],
|
|
274
|
+
customFields: [],
|
|
275
|
+
priority: 'medium',
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Convert a full Activity to a flat representation for legacy API compatibility.
|
|
281
|
+
*/
|
|
282
|
+
export function toFlatActivity(activity: import('../core/types.js').Activity): FlatActivity {
|
|
283
|
+
return {
|
|
284
|
+
id: activity.id,
|
|
285
|
+
type: activity.type,
|
|
286
|
+
description: activity.description,
|
|
287
|
+
contactId: activity.contactId,
|
|
288
|
+
dealId: activity.dealId,
|
|
289
|
+
userId: activity.createdBy || 'system',
|
|
290
|
+
timestamp: activity.timestamp,
|
|
291
|
+
metadata: activity.metadata as Record<string, unknown>,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Convert a flat activity input to a full Activity structure.
|
|
297
|
+
*/
|
|
298
|
+
export function fromFlatActivityInput(input: Partial<FlatActivity> & { type: import('../core/types.js').ActivityType; description: string }): Partial<import('../core/types.js').Activity> {
|
|
299
|
+
return {
|
|
300
|
+
type: input.type,
|
|
301
|
+
title: input.description.slice(0, 100), // Use first 100 chars as title
|
|
302
|
+
description: input.description,
|
|
303
|
+
contactId: input.contactId,
|
|
304
|
+
dealId: input.dealId,
|
|
305
|
+
createdBy: input.userId,
|
|
306
|
+
timestamp: input.timestamp || new Date().toISOString(),
|
|
307
|
+
tags: [],
|
|
308
|
+
customFields: [],
|
|
309
|
+
metadata: input.metadata || {},
|
|
310
|
+
};
|
|
311
|
+
}
|