Coverage for src / local_deep_research / database / library_init.py: 68%
63 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-01-11 00:51 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2026-01-11 00:51 +0000
1"""
2Database initialization for Library - Unified Document Architecture.
4This module handles:
5- Seeding source_types table with predefined types
6- Creating the default "Library" collection
7- Must be called on app startup for each user
8"""
10import uuid
11from loguru import logger
12from sqlalchemy.exc import IntegrityError
14from .models import SourceType, Collection
15from .session_context import get_user_db_session
18def seed_source_types(username: str, password: str = None) -> None:
19 """
20 Seed the source_types table with predefined document source types.
22 Args:
23 username: User to seed types for
24 password: User's password (optional, uses session context)
25 """
26 predefined_types = [
27 {
28 "name": "research_download",
29 "display_name": "Research Download",
30 "description": "Documents downloaded from research sessions (arXiv, PubMed, etc.)",
31 "icon": "download",
32 },
33 {
34 "name": "user_upload",
35 "display_name": "User Upload",
36 "description": "Documents manually uploaded by the user",
37 "icon": "upload",
38 },
39 {
40 "name": "manual_entry",
41 "display_name": "Manual Entry",
42 "description": "Documents manually created or entered",
43 "icon": "edit",
44 },
45 ]
47 try:
48 with get_user_db_session(username, password) as session:
49 for type_data in predefined_types:
50 # Check if type already exists
51 existing = (
52 session.query(SourceType)
53 .filter_by(name=type_data["name"])
54 .first()
55 )
57 if not existing:
58 source_type = SourceType(id=str(uuid.uuid4()), **type_data)
59 session.add(source_type)
60 logger.info(f"Created source type: {type_data['name']}")
62 session.commit()
63 logger.info("Source types seeded successfully")
65 except IntegrityError as e:
66 logger.warning(f"Source types may already exist: {e}")
67 except Exception:
68 logger.exception("Error seeding source types")
69 raise
72def ensure_default_library_collection(
73 username: str, password: str = None
74) -> str:
75 """
76 Ensure the default "Library" collection exists for a user.
77 Creates it if it doesn't exist.
79 Args:
80 username: User to check/create library for
81 password: User's password (optional, uses session context)
83 Returns:
84 UUID of the Library collection
85 """
86 try:
87 with get_user_db_session(username, password) as session:
88 # Check if default library exists
89 library = (
90 session.query(Collection).filter_by(is_default=True).first()
91 )
93 if library:
94 logger.debug(f"Default Library collection exists: {library.id}")
95 return library.id
97 # Create default Library collection
98 library_id = str(uuid.uuid4())
99 library = Collection(
100 id=library_id,
101 name="Library",
102 description="Default collection for research downloads and documents",
103 collection_type="default_library",
104 is_default=True,
105 )
106 session.add(library)
107 session.commit()
109 logger.info(f"Created default Library collection: {library_id}")
110 return library_id
112 except Exception:
113 logger.exception("Error ensuring default Library collection")
114 raise
117def initialize_library_for_user(username: str, password: str = None) -> dict:
118 """
119 Complete initialization of library system for a user.
120 Seeds source types and ensures default Library collection exists.
122 Args:
123 username: User to initialize for
124 password: User's password (optional, uses session context)
126 Returns:
127 Dict with initialization results
128 """
129 results = {
130 "source_types_seeded": False,
131 "library_collection_id": None,
132 "success": False,
133 }
135 try:
136 # Seed source types
137 seed_source_types(username, password)
138 results["source_types_seeded"] = True
140 # Ensure Library collection
141 library_id = ensure_default_library_collection(username, password)
142 results["library_collection_id"] = library_id
144 results["success"] = True
145 logger.info(f"Library initialization complete for user: {username}")
147 except Exception as e:
148 logger.exception(f"Library initialization failed for {username}")
149 results["error"] = str(e)
151 return results
154def get_default_library_id(username: str, password: str = None) -> str:
155 """
156 Get the ID of the default Library collection for a user.
157 Creates it if it doesn't exist.
159 Args:
160 username: User to get library for
161 password: User's password (optional, uses session context)
163 Returns:
164 UUID of the Library collection
165 """
166 return ensure_default_library_collection(username, password)
169def get_source_type_id(
170 username: str, type_name: str, password: str = None
171) -> str:
172 """
173 Get the ID of a source type by name.
175 Args:
176 username: User to query for
177 type_name: Name of source type (e.g., 'research_download', 'user_upload')
178 password: User's password (optional, uses session context)
180 Returns:
181 UUID of the source type
183 Raises:
184 ValueError: If source type not found
185 """
186 try:
187 with get_user_db_session(username, password) as session:
188 source_type = (
189 session.query(SourceType).filter_by(name=type_name).first()
190 )
192 if not source_type:
193 raise ValueError(f"Source type not found: {type_name}")
195 return source_type.id
197 except Exception:
198 logger.exception("Error getting source type ID")
199 raise