@@ -13,9 +13,17 @@ import * as os from "os";
1313import { EnterpriseIntegration } from "@devlog/types" ;
1414import { StorageConfig } from "./storage/storage-provider.js" ;
1515
16+ export interface SyncStrategy {
17+ sourceOfTruth : 'local' | 'external' | 'manual' ;
18+ conflictResolution : 'local-wins' | 'external-wins' | 'most-recent' | 'manual' ;
19+ syncInterval ?: number ; // minutes
20+ autoSync ?: boolean ;
21+ }
22+
1623export interface DevlogConfig {
1724 storage : StorageConfig ;
1825 integrations ?: EnterpriseIntegration ;
26+ syncStrategy ?: SyncStrategy ;
1927 workspaceRoot ?: string ;
2028 workspaceId ?: string ; // Added for workspace identification
2129}
@@ -77,15 +85,6 @@ export class ConfigurationManager {
7785 * Detect the best storage configuration automatically
7886 */
7987 async detectBestStorage ( ) : Promise < StorageConfig > {
80- // Check for enterprise integrations first
81- const integrations = await this . detectEnterpriseIntegrations ( ) ;
82- if ( integrations && this . hasEnterpriseIntegrations ( integrations ) ) {
83- return {
84- type : "enterprise" ,
85- options : { integrations }
86- } ;
87- }
88-
8988 // Check for database environment variables
9089 if ( process . env . DATABASE_URL ) {
9190 const dbUrl = process . env . DATABASE_URL ;
@@ -152,27 +151,6 @@ export class ConfigurationManager {
152151 bestFor : string [ ] ;
153152 } > {
154153 return [
155- {
156- type : "enterprise" ,
157- name : "Enterprise Integration" ,
158- description : "Store devlogs directly in enterprise tools (Jira, ADO, GitHub)" ,
159- pros : [
160- "No local storage duplication" ,
161- "Integrated with existing workflows" ,
162- "Automatic synchronization" ,
163- "Enterprise-grade security"
164- ] ,
165- cons : [
166- "Requires enterprise tool access" ,
167- "Limited offline capability" ,
168- "Dependent on external services"
169- ] ,
170- bestFor : [
171- "Teams using Jira, Azure DevOps, or GitHub Issues" ,
172- "Enterprise environments" ,
173- "Distributed teams"
174- ]
175- } ,
176154 {
177155 type : "sqlite" ,
178156 name : "SQLite Database" ,
@@ -181,7 +159,8 @@ export class ConfigurationManager {
181159 "Fast performance" ,
182160 "Full-text search" ,
183161 "ACID transactions" ,
184- "No server required"
162+ "No server required" ,
163+ "Works offline"
185164 ] ,
186165 cons : [
187166 "Single-user access" ,
@@ -191,7 +170,8 @@ export class ConfigurationManager {
191170 bestFor : [
192171 "Individual developers" ,
193172 "Local development" ,
194- "Fast prototyping"
173+ "Fast prototyping" ,
174+ "Offline work"
195175 ]
196176 } ,
197177 {
@@ -202,7 +182,8 @@ export class ConfigurationManager {
202182 "Multi-user support" ,
203183 "Advanced querying" ,
204184 "Scalable" ,
205- "Full ACID compliance"
185+ "Full ACID compliance" ,
186+ "Concurrent access"
206187 ] ,
207188 cons : [
208189 "Requires database server" ,
@@ -212,7 +193,8 @@ export class ConfigurationManager {
212193 bestFor : [
213194 "Team collaboration" ,
214195 "Production deployments" ,
215- "Web applications"
196+ "Web applications" ,
197+ "Multi-user environments"
216198 ]
217199 } ,
218200 {
@@ -223,7 +205,8 @@ export class ConfigurationManager {
223205 "Wide adoption" ,
224206 "Good performance" ,
225207 "Multi-user support" ,
226- "Full-text search"
208+ "Full-text search" ,
209+ "Mature ecosystem"
227210 ] ,
228211 cons : [
229212 "Requires database server" ,
@@ -233,27 +216,82 @@ export class ConfigurationManager {
233216 bestFor : [
234217 "Web applications" ,
235218 "Existing MySQL infrastructure" ,
236- "Team collaboration"
219+ "Team collaboration" ,
220+ "LAMP stack projects"
237221 ]
238222 }
239223 ] ;
240224 }
241225
226+ /**
227+ * Detect the best sync strategy based on environment and integrations
228+ */
229+ async detectSyncStrategy ( integrations ?: EnterpriseIntegration ) : Promise < SyncStrategy > {
230+ // Default sync strategy
231+ const defaultStrategy : SyncStrategy = {
232+ sourceOfTruth : 'local' ,
233+ conflictResolution : 'local-wins' ,
234+ syncInterval : 15 , // 15 minutes
235+ autoSync : true
236+ } ;
237+
238+ // If no integrations configured, return minimal strategy
239+ if ( ! integrations || ! this . hasEnterpriseIntegrations ( integrations ) ) {
240+ return {
241+ sourceOfTruth : 'local' ,
242+ conflictResolution : 'local-wins' ,
243+ autoSync : false
244+ } ;
245+ }
246+
247+ // Check for environment-specific sync preferences
248+ if ( process . env . DEVLOG_SYNC_STRATEGY ) {
249+ const strategy = process . env . DEVLOG_SYNC_STRATEGY . toLowerCase ( ) ;
250+ switch ( strategy ) {
251+ case 'external' :
252+ return {
253+ ...defaultStrategy ,
254+ sourceOfTruth : 'external' ,
255+ conflictResolution : 'external-wins'
256+ } ;
257+ case 'manual' :
258+ return {
259+ ...defaultStrategy ,
260+ sourceOfTruth : 'manual' ,
261+ conflictResolution : 'manual' ,
262+ autoSync : false
263+ } ;
264+ }
265+ }
266+
267+ // Configure sync interval from environment
268+ if ( process . env . DEVLOG_SYNC_INTERVAL ) {
269+ const interval = parseInt ( process . env . DEVLOG_SYNC_INTERVAL ) ;
270+ if ( ! isNaN ( interval ) && interval > 0 ) {
271+ defaultStrategy . syncInterval = interval ;
272+ }
273+ }
274+
275+ return defaultStrategy ;
276+ }
277+
242278 private async createDefaultConfig ( ) : Promise < DevlogConfig > {
243279 const storage = await this . detectBestStorage ( ) ;
244280 const integrations = await this . detectEnterpriseIntegrations ( ) ;
281+ const syncStrategy = await this . detectSyncStrategy ( integrations ) ;
245282 const detectedRoot = await this . detectProjectRoot ( ) ;
246283 const workspace = await this . getWorkspaceStructure ( detectedRoot || undefined ) ;
247284
248285 return {
249286 storage,
250287 integrations,
288+ syncStrategy,
251289 workspaceRoot : detectedRoot || this . workspaceRoot ,
252290 workspaceId : path . basename ( workspace . workspaceDir )
253291 } ;
254292 }
255293
256- private async detectEnterpriseIntegrations ( ) : Promise < EnterpriseIntegration | undefined > {
294+ async detectEnterpriseIntegrations ( ) : Promise < EnterpriseIntegration | undefined > {
257295 const integrations : EnterpriseIntegration = { } ;
258296
259297 // Check for Jira configuration
0 commit comments