@@ -28,7 +28,7 @@ export interface DatabaseProjectManagerOptions {
2828 */
2929export class DatabaseProjectManager implements ProjectManager {
3030 private repository : Repository < ProjectEntity > ;
31- private currentProjectId : string | null = null ;
31+ private currentProjectId : number | null = null ;
3232 private initialized = false ;
3333
3434 constructor ( private options : DatabaseProjectManagerOptions ) {
@@ -71,21 +71,32 @@ export class DatabaseProjectManager implements ProjectManager {
7171 * Create default project
7272 */
7373 private async createDefaultProject ( ) : Promise < void > {
74- const defaultProject : Omit < ProjectMetadata , 'createdAt' | 'lastAccessedAt' > = {
75- id : 'default' ,
74+ const defaultProject : Omit < ProjectMetadata , 'id' | 'createdAt' | 'lastAccessedAt' > = {
7675 name : 'Default Project' ,
7776 description : 'Default devlog project' ,
7877 settings : {
7978 defaultPriority : 'medium' ,
8079 } ,
81- tags : [ ] ,
8280 ...this . options . defaultProjectConfig ,
8381 } ;
8482
85- // Force the ID to be 'default' even if overridden
86- defaultProject . id = 'default' ;
83+ // Create project directly without initialization check since this is called during initialization
84+ const existing = await this . repository . findOne ( { where : { name : defaultProject . name } } ) ;
85+ if ( existing ) {
86+ return ; // Default project already exists
87+ }
88+
89+ // Check project limits
90+ if ( this . options . maxProjects ) {
91+ const projectCount = await this . repository . count ( ) ;
92+ if ( projectCount >= this . options . maxProjects ) {
93+ throw new Error ( `Maximum number of projects (${ this . options . maxProjects } ) reached` ) ;
94+ }
95+ }
8796
88- await this . createProject ( defaultProject ) ;
97+ // Create and save new project entity
98+ const entity = ProjectEntity . fromProjectData ( defaultProject ) ;
99+ await this . repository . save ( entity ) ;
89100 }
90101
91102 private ensureInitialized ( ) : void {
@@ -102,7 +113,7 @@ export class DatabaseProjectManager implements ProjectManager {
102113 return entities . map ( ( entity ) => entity . toProjectMetadata ( ) ) ;
103114 }
104115
105- async getProject ( id : string ) : Promise < ProjectMetadata | null > {
116+ async getProject ( id : number ) : Promise < ProjectMetadata | null > {
106117 this . ensureInitialized ( ) ;
107118 const entity = await this . repository . findOne ( { where : { id } } ) ;
108119
@@ -118,16 +129,10 @@ export class DatabaseProjectManager implements ProjectManager {
118129 }
119130
120131 async createProject (
121- project : Omit < ProjectMetadata , 'createdAt' | 'lastAccessedAt' > ,
132+ project : Omit < ProjectMetadata , 'id' | ' createdAt' | 'lastAccessedAt' > ,
122133 ) : Promise < ProjectMetadata > {
123134 this . ensureInitialized ( ) ;
124135
125- // Check if project already exists
126- const existing = await this . repository . findOne ( { where : { id : project . id } } ) ;
127- if ( existing ) {
128- throw new Error ( `Project '${ project . id } ' already exists` ) ;
129- }
130-
131136 // Check project limits
132137 if ( this . options . maxProjects ) {
133138 const projectCount = await this . repository . count ( ) ;
@@ -143,12 +148,12 @@ export class DatabaseProjectManager implements ProjectManager {
143148 return savedEntity . toProjectMetadata ( ) ;
144149 }
145150
146- async updateProject ( id : string , updates : Partial < ProjectMetadata > ) : Promise < ProjectMetadata > {
151+ async updateProject ( id : number , updates : Partial < ProjectMetadata > ) : Promise < ProjectMetadata > {
147152 this . ensureInitialized ( ) ;
148153
149154 const entity = await this . repository . findOne ( { where : { id } } ) ;
150155 if ( ! entity ) {
151- throw new Error ( `Project '${ id } ' not found` ) ;
156+ throw new Error ( `Project with ID '${ id } ' not found` ) ;
152157 }
153158
154159 // Prevent changing project ID
@@ -163,54 +168,54 @@ export class DatabaseProjectManager implements ProjectManager {
163168 return savedEntity . toProjectMetadata ( ) ;
164169 }
165170
166- async deleteProject ( id : string ) : Promise < void > {
171+ async deleteProject ( id : number ) : Promise < void > {
167172 this . ensureInitialized ( ) ;
168173
169- // Prevent deleting the default project
170- if ( id === 'default' ) {
171- throw new Error ( 'Cannot delete the default project' ) ;
172- }
173-
174174 const result = await this . repository . delete ( { id } ) ;
175175 if ( result . affected === 0 ) {
176- throw new Error ( `Project '${ id } ' not found` ) ;
176+ throw new Error ( `Project with ID '${ id } ' not found` ) ;
177177 }
178178
179- // If this was the current project, reset to default
179+ // If this was the current project, reset to null
180180 if ( this . currentProjectId === id ) {
181181 this . currentProjectId = null ;
182182 }
183183 }
184184
185- async getDefaultProject ( ) : Promise < string > {
185+ async getDefaultProject ( ) : Promise < number > {
186186 this . ensureInitialized ( ) ;
187- // For now, we'll use a simple default project approach
188- // In the future, this could be stored in a settings table
189- return 'default' ;
187+ // Get the first project (lowest ID) as the default
188+ const defaultProject = await this . repository . findOne ( {
189+ order : { id : 'ASC' } ,
190+ } ) ;
191+
192+ if ( ! defaultProject ) {
193+ throw new Error ( 'No projects found' ) ;
194+ }
195+
196+ return defaultProject . id ;
190197 }
191198
192- async setDefaultProject ( id : string ) : Promise < void > {
199+ async setDefaultProject ( id : number ) : Promise < void > {
193200 this . ensureInitialized ( ) ;
194201
195202 // Verify project exists
196203 const project = await this . repository . findOne ( { where : { id } } ) ;
197204 if ( ! project ) {
198- throw new Error ( `Project '${ id } ' not found` ) ;
205+ throw new Error ( `Project with ID '${ id } ' not found` ) ;
199206 }
200207
201- // For now, we'll keep the default as ' default'
208+ // For now, we'll consider the first project (lowest ID) as default
202209 // In the future, this could be stored in a settings table
203- if ( id !== 'default' ) {
204- throw new Error ( 'Setting custom default project not yet supported in database mode' ) ;
205- }
210+ // This is a no-op for now since we determine default by ID ordering
206211 }
207212
208- async switchToProject ( id : string ) : Promise < ProjectContext > {
213+ async switchToProject ( id : number ) : Promise < ProjectContext > {
209214 this . ensureInitialized ( ) ;
210215
211216 const entity = await this . repository . findOne ( { where : { id } } ) ;
212217 if ( ! entity ) {
213- throw new Error ( `Project '${ id } ' not found` ) ;
218+ throw new Error ( `Project with ID '${ id } ' not found` ) ;
214219 }
215220
216221 // Update last accessed time
@@ -221,10 +226,11 @@ export class DatabaseProjectManager implements ProjectManager {
221226 this . currentProjectId = id ;
222227
223228 const project = entity . toProjectMetadata ( ) ;
229+ const defaultProjectId = await this . getDefaultProject ( ) ;
224230 return {
225231 projectId : id ,
226232 project,
227- isDefault : id === 'default' ,
233+ isDefault : id === defaultProjectId ,
228234 } ;
229235 }
230236
@@ -235,7 +241,11 @@ export class DatabaseProjectManager implements ProjectManager {
235241
236242 // Fall back to default project if no current project set
237243 if ( ! projectId ) {
238- projectId = await this . getDefaultProject ( ) ;
244+ try {
245+ projectId = await this . getDefaultProject ( ) ;
246+ } catch {
247+ return null ; // No projects exist
248+ }
239249 }
240250
241251 const entity = await this . repository . findOne ( { where : { id : projectId } } ) ;
@@ -244,10 +254,11 @@ export class DatabaseProjectManager implements ProjectManager {
244254 }
245255
246256 const project = entity . toProjectMetadata ( ) ;
257+ const defaultProjectId = await this . getDefaultProject ( ) ;
247258 return {
248259 projectId,
249260 project,
250- isDefault : projectId === 'default' ,
261+ isDefault : projectId === defaultProjectId ,
251262 } ;
252263 }
253264}
0 commit comments