eggi-ai-db-schema-2 12.54.2

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.
Files changed (188) hide show
  1. package/CHANGELOG.md +750 -0
  2. package/README.md +655 -0
  3. package/dist/config/database.d.ts +28 -0
  4. package/dist/config/database.d.ts.map +1 -0
  5. package/dist/config/database.js +72 -0
  6. package/dist/config/database.js.map +1 -0
  7. package/dist/index.d.ts +28 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +199 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/database-service.d.ts +689 -0
  12. package/dist/lib/database-service.d.ts.map +1 -0
  13. package/dist/lib/database-service.js +1362 -0
  14. package/dist/lib/database-service.js.map +1 -0
  15. package/dist/lib/db-types.d.ts +167 -0
  16. package/dist/lib/db-types.d.ts.map +1 -0
  17. package/dist/lib/db-types.js +28 -0
  18. package/dist/lib/db-types.js.map +1 -0
  19. package/dist/lib/db.d.ts +58 -0
  20. package/dist/lib/db.d.ts.map +1 -0
  21. package/dist/lib/db.js +292 -0
  22. package/dist/lib/db.js.map +1 -0
  23. package/dist/lib/index.d.ts +11 -0
  24. package/dist/lib/index.d.ts.map +1 -0
  25. package/dist/lib/index.js +26 -0
  26. package/dist/lib/index.js.map +1 -0
  27. package/dist/lib/pg-client.d.ts +50 -0
  28. package/dist/lib/pg-client.d.ts.map +1 -0
  29. package/dist/lib/pg-client.js +106 -0
  30. package/dist/lib/pg-client.js.map +1 -0
  31. package/dist/lib/schema.d.ts +298 -0
  32. package/dist/lib/schema.d.ts.map +1 -0
  33. package/dist/lib/schema.js +12 -0
  34. package/dist/lib/schema.js.map +1 -0
  35. package/dist/migration-manager.d.ts +49 -0
  36. package/dist/migration-manager.d.ts.map +1 -0
  37. package/dist/migration-manager.js +282 -0
  38. package/dist/migration-manager.js.map +1 -0
  39. package/dist/queries/minimal-connections.d.ts +31 -0
  40. package/dist/queries/minimal-connections.d.ts.map +1 -0
  41. package/dist/queries/minimal-connections.js +143 -0
  42. package/dist/queries/minimal-connections.js.map +1 -0
  43. package/dist/schema.ts +340 -0
  44. package/dist/seed.d.ts +8 -0
  45. package/dist/seed.d.ts.map +1 -0
  46. package/dist/seed.js +40 -0
  47. package/dist/seed.js.map +1 -0
  48. package/dist/types/index.d.ts +7 -0
  49. package/dist/types/index.d.ts.map +1 -0
  50. package/dist/types/index.js +23 -0
  51. package/dist/types/index.js.map +1 -0
  52. package/dist/types/types.d.ts +77 -0
  53. package/dist/types/types.d.ts.map +1 -0
  54. package/dist/types/types.js +3 -0
  55. package/dist/types/types.js.map +1 -0
  56. package/dist/utils/authenticated-user-operations.d.ts +110 -0
  57. package/dist/utils/authenticated-user-operations.d.ts.map +1 -0
  58. package/dist/utils/authenticated-user-operations.js +292 -0
  59. package/dist/utils/authenticated-user-operations.js.map +1 -0
  60. package/dist/utils/authentication-operations.d.ts +48 -0
  61. package/dist/utils/authentication-operations.d.ts.map +1 -0
  62. package/dist/utils/authentication-operations.js +172 -0
  63. package/dist/utils/authentication-operations.js.map +1 -0
  64. package/dist/utils/company-mapping-job-operations.d.ts +103 -0
  65. package/dist/utils/company-mapping-job-operations.d.ts.map +1 -0
  66. package/dist/utils/company-mapping-job-operations.js +413 -0
  67. package/dist/utils/company-mapping-job-operations.js.map +1 -0
  68. package/dist/utils/company-sheet-upload-operations.d.ts +53 -0
  69. package/dist/utils/company-sheet-upload-operations.d.ts.map +1 -0
  70. package/dist/utils/company-sheet-upload-operations.js +135 -0
  71. package/dist/utils/company-sheet-upload-operations.js.map +1 -0
  72. package/dist/utils/contact-operations.d.ts +70 -0
  73. package/dist/utils/contact-operations.d.ts.map +1 -0
  74. package/dist/utils/contact-operations.js +294 -0
  75. package/dist/utils/contact-operations.js.map +1 -0
  76. package/dist/utils/forager-linkedin-operations.d.ts +74 -0
  77. package/dist/utils/forager-linkedin-operations.d.ts.map +1 -0
  78. package/dist/utils/forager-linkedin-operations.js +778 -0
  79. package/dist/utils/forager-linkedin-operations.js.map +1 -0
  80. package/dist/utils/ghost-genius-linkedin-operations.d.ts +23 -0
  81. package/dist/utils/ghost-genius-linkedin-operations.d.ts.map +1 -0
  82. package/dist/utils/ghost-genius-linkedin-operations.js +282 -0
  83. package/dist/utils/ghost-genius-linkedin-operations.js.map +1 -0
  84. package/dist/utils/index.d.ts +29 -0
  85. package/dist/utils/index.d.ts.map +1 -0
  86. package/dist/utils/index.js +77 -0
  87. package/dist/utils/index.js.map +1 -0
  88. package/dist/utils/introduction-request-operations.d.ts +159 -0
  89. package/dist/utils/introduction-request-operations.d.ts.map +1 -0
  90. package/dist/utils/introduction-request-operations.js +481 -0
  91. package/dist/utils/introduction-request-operations.js.map +1 -0
  92. package/dist/utils/invitation-operations.d.ts +141 -0
  93. package/dist/utils/invitation-operations.d.ts.map +1 -0
  94. package/dist/utils/invitation-operations.js +749 -0
  95. package/dist/utils/invitation-operations.js.map +1 -0
  96. package/dist/utils/linkedin-account-operations.d.ts +45 -0
  97. package/dist/utils/linkedin-account-operations.d.ts.map +1 -0
  98. package/dist/utils/linkedin-account-operations.js +279 -0
  99. package/dist/utils/linkedin-account-operations.js.map +1 -0
  100. package/dist/utils/linkedin-account-relationship-operations.d.ts +77 -0
  101. package/dist/utils/linkedin-account-relationship-operations.d.ts.map +1 -0
  102. package/dist/utils/linkedin-account-relationship-operations.js +274 -0
  103. package/dist/utils/linkedin-account-relationship-operations.js.map +1 -0
  104. package/dist/utils/linkedin-data-operations.d.ts +102 -0
  105. package/dist/utils/linkedin-data-operations.d.ts.map +1 -0
  106. package/dist/utils/linkedin-data-operations.js +613 -0
  107. package/dist/utils/linkedin-data-operations.js.map +1 -0
  108. package/dist/utils/linkedin-identifier-utils.d.ts +31 -0
  109. package/dist/utils/linkedin-identifier-utils.d.ts.map +1 -0
  110. package/dist/utils/linkedin-identifier-utils.js +63 -0
  111. package/dist/utils/linkedin-identifier-utils.js.map +1 -0
  112. package/dist/utils/linkedin-profile-cache.d.ts +131 -0
  113. package/dist/utils/linkedin-profile-cache.d.ts.map +1 -0
  114. package/dist/utils/linkedin-profile-cache.js +418 -0
  115. package/dist/utils/linkedin-profile-cache.js.map +1 -0
  116. package/dist/utils/llm-inference-job-operations.d.ts +116 -0
  117. package/dist/utils/llm-inference-job-operations.d.ts.map +1 -0
  118. package/dist/utils/llm-inference-job-operations.js +266 -0
  119. package/dist/utils/llm-inference-job-operations.js.map +1 -0
  120. package/dist/utils/mapping-job-operations.d.ts +272 -0
  121. package/dist/utils/mapping-job-operations.d.ts.map +1 -0
  122. package/dist/utils/mapping-job-operations.js +833 -0
  123. package/dist/utils/mapping-job-operations.js.map +1 -0
  124. package/dist/utils/mapping-operations.d.ts +80 -0
  125. package/dist/utils/mapping-operations.d.ts.map +1 -0
  126. package/dist/utils/mapping-operations.js +318 -0
  127. package/dist/utils/mapping-operations.js.map +1 -0
  128. package/dist/utils/on-demand-mapping-operations.d.ts +199 -0
  129. package/dist/utils/on-demand-mapping-operations.d.ts.map +1 -0
  130. package/dist/utils/on-demand-mapping-operations.js +728 -0
  131. package/dist/utils/on-demand-mapping-operations.js.map +1 -0
  132. package/dist/utils/onboarding-operations.d.ts +53 -0
  133. package/dist/utils/onboarding-operations.d.ts.map +1 -0
  134. package/dist/utils/onboarding-operations.js +223 -0
  135. package/dist/utils/onboarding-operations.js.map +1 -0
  136. package/dist/utils/organization-assignment-job-operations.d.ts +258 -0
  137. package/dist/utils/organization-assignment-job-operations.d.ts.map +1 -0
  138. package/dist/utils/organization-assignment-job-operations.js +881 -0
  139. package/dist/utils/organization-assignment-job-operations.js.map +1 -0
  140. package/dist/utils/organization-assignment-operations.d.ts +59 -0
  141. package/dist/utils/organization-assignment-operations.d.ts.map +1 -0
  142. package/dist/utils/organization-assignment-operations.js +130 -0
  143. package/dist/utils/organization-assignment-operations.js.map +1 -0
  144. package/dist/utils/organization-operations.d.ts +275 -0
  145. package/dist/utils/organization-operations.d.ts.map +1 -0
  146. package/dist/utils/organization-operations.js +993 -0
  147. package/dist/utils/organization-operations.js.map +1 -0
  148. package/dist/utils/organization-relationship-operations.d.ts +59 -0
  149. package/dist/utils/organization-relationship-operations.d.ts.map +1 -0
  150. package/dist/utils/organization-relationship-operations.js +240 -0
  151. package/dist/utils/organization-relationship-operations.js.map +1 -0
  152. package/dist/utils/quota-operations.d.ts +107 -0
  153. package/dist/utils/quota-operations.d.ts.map +1 -0
  154. package/dist/utils/quota-operations.js +692 -0
  155. package/dist/utils/quota-operations.js.map +1 -0
  156. package/dist/utils/recursive-mapping-job-operations.d.ts +42 -0
  157. package/dist/utils/recursive-mapping-job-operations.d.ts.map +1 -0
  158. package/dist/utils/recursive-mapping-job-operations.js +169 -0
  159. package/dist/utils/recursive-mapping-job-operations.js.map +1 -0
  160. package/dist/utils/relationship-operations.d.ts +130 -0
  161. package/dist/utils/relationship-operations.d.ts.map +1 -0
  162. package/dist/utils/relationship-operations.js +329 -0
  163. package/dist/utils/relationship-operations.js.map +1 -0
  164. package/dist/utils/sales-pipeline-operations.d.ts +143 -0
  165. package/dist/utils/sales-pipeline-operations.d.ts.map +1 -0
  166. package/dist/utils/sales-pipeline-operations.js +649 -0
  167. package/dist/utils/sales-pipeline-operations.js.map +1 -0
  168. package/dist/utils/skills-operations.d.ts +117 -0
  169. package/dist/utils/skills-operations.d.ts.map +1 -0
  170. package/dist/utils/skills-operations.js +487 -0
  171. package/dist/utils/skills-operations.js.map +1 -0
  172. package/dist/utils/subscription-operations.d.ts +123 -0
  173. package/dist/utils/subscription-operations.d.ts.map +1 -0
  174. package/dist/utils/subscription-operations.js +391 -0
  175. package/dist/utils/subscription-operations.js.map +1 -0
  176. package/dist/utils/unipile-account-operations.d.ts +96 -0
  177. package/dist/utils/unipile-account-operations.d.ts.map +1 -0
  178. package/dist/utils/unipile-account-operations.js +255 -0
  179. package/dist/utils/unipile-account-operations.js.map +1 -0
  180. package/dist/utils/user-industry-operations.d.ts +80 -0
  181. package/dist/utils/user-industry-operations.d.ts.map +1 -0
  182. package/dist/utils/user-industry-operations.js +237 -0
  183. package/dist/utils/user-industry-operations.js.map +1 -0
  184. package/dist/utils/user-operations.d.ts +87 -0
  185. package/dist/utils/user-operations.d.ts.map +1 -0
  186. package/dist/utils/user-operations.js +212 -0
  187. package/dist/utils/user-operations.js.map +1 -0
  188. package/package.json +98 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,750 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [12.13.0] - 2025-11-18
6
+
7
+ ### Added
8
+
9
+ - **Organizations Array in Mapping Jobs Response**: Added `organizations` array to `OnDemandMappingJobMinimal` interface
10
+ - Each mapping job now includes which organizations it was exported to
11
+ - Supports multiple organizations per mapping job
12
+ - Includes organization `id`, `name`, and `workspaceType` (INDIVIDUALS or BUSINESS)
13
+ - Enables frontend to display "Exported to Personal Workspace" or "Exported to [Business Name]"
14
+
15
+ ### Changed
16
+
17
+ - **Mapping Jobs Query**: Updated `getOnDemandMappingJobsMinimal()` to join with `organization_assignment_jobs` and `organizations` tables
18
+ - Returns all unique organizations a mapping job was exported to
19
+ - Handles multiple organization assignments per mapping job
20
+
21
+ ## [12.12.0] - 2025-11-18
22
+
23
+ ### Added
24
+
25
+ - **Unlimited Quota Support**: Added support for unlimited quotas using `null` instead of `-1`
26
+ - `quota_limit` column now allows `NULL` values (migration `0047_make_quota_limit_nullable_for_unlimited.sql`)
27
+ - `null` quotaLimit indicates unlimited (PRO_VERSION with active subscription, not trialing)
28
+ - Usage is still tracked even for unlimited quotas
29
+
30
+ ### Changed
31
+
32
+ - **Quota System**: Updated quota operations to always return both daily and monthly quotas for all organizations
33
+ - `getAllQuotasForUser()` now ensures both daily and monthly quotas are returned for every organization
34
+ - Creates default quota records if they don't exist in the database
35
+ - `getQuotaLimit()` returns `null` for PRO_VERSION with active subscription status
36
+ - `checkAndIncrementQuota()` handles `null` quota limits correctly (always allows and increments)
37
+ - `getQuotaStatus()` returns `null` for remainingQuota and quotaLimit when unlimited
38
+
39
+ - **UTC-Based Period Calculations**: Fixed timezone issues in quota period calculations
40
+ - `getDailyPeriod()` and `getMonthlyPeriod()` now use UTC methods (`getUTCFullYear()`, `getUTCMonth()`, `getUTCDate()`, `Date.UTC()`)
41
+ - Ensures consistent date boundaries regardless of server timezone
42
+ - Prevents quota period mismatches when server is in different timezone than UTC
43
+
44
+ ### Migration
45
+
46
+ - **Migration File**: `0047_make_quota_limit_nullable_for_unlimited.sql`
47
+ - Makes `quota_limit` column nullable in `monitoring.mapping_job_quotas` table
48
+ - Updates column comment to reflect that NULL means unlimited
49
+
50
+ ## [Unreleased]
51
+
52
+ ### Added
53
+
54
+ - **Ghost Genius Provider Support**: Added support for Ghost Genius LinkedIn profiles alongside Forager
55
+ - New module: `ghost-genius-linkedin-operations.ts` with `findLinkedInAccountByAcoa()` and `findOrCreateLinkedInAccountByAcoa()`
56
+ - New function: `storeCompleteLinkedInProfileByAcoa()` for Ghost Genius profile storage
57
+ - Database migration: `0031_make_forager_id_optional_for_ghost_genius.sql` makes `forager_id` nullable
58
+ - Updated constraints to allow `forager_id` to be null while ensuring at least one identifier exists
59
+ - Separate cache tables and operations for Forager and Ghost Genius providers
60
+
61
+ ### Changed
62
+
63
+ - **Database Schema**: `linkedin.accounts.forager_id` is now nullable to support Ghost Genius profiles
64
+ - **LinkedIn Operations**: Separated Forager and Ghost Genius operations into distinct modules for better modularity
65
+ - `forager-linkedin-operations.ts`: Forager-specific operations (uses `forager_id`)
66
+ - `ghost-genius-linkedin-operations.ts`: Ghost Genius-specific operations (uses ACoA identifier)
67
+ - **Type Exports**: Updated exports to include Ghost Genius operations while maintaining backward compatibility
68
+
69
+ ### Migration
70
+
71
+ - **Migration File**: `0031_make_forager_id_optional_for_ghost_genius.sql`
72
+ - Makes `forager_id` column nullable
73
+ - Updates unique constraint to allow multiple NULL values
74
+ - Updates identifier check constraint to allow `forager_id` to be NULL
75
+
76
+ ## [11.14.7] - 2025-10-20
77
+
78
+ - chore: minor docs touch to trigger CI publish
79
+
80
+ ## [11.12.0] - 2025-10-18
81
+
82
+ ### Added
83
+
84
+ - **Organization Assignment Jobs Table**: New `monitoring.organization_assignment_jobs` table for tracking organization assignment job lifecycle
85
+ - `id`: Serial primary key
86
+ - `mapping_job_id`: Foreign key to mapping jobs (cascade delete)
87
+ - `organization_id`: Foreign key to organizations (cascade delete)
88
+ - `created_at`: Timestamp when job was created
89
+ - `started_at`: Timestamp when job started processing (defaults to created_at)
90
+ - `completed_at`: Timestamp when job completed (nullable)
91
+ - `metadata`: JSONB column for job statistics (relationships_removed, relationships_added, contributor_role_action, error_details)
92
+ - Indexes on mapping_job_id, organization_id, created_at, completed_at for query performance
93
+ - Comments on table and columns for documentation
94
+
95
+ - **Organization Assignment Job Operations**: New utility functions in `organization-assignment-job-operations.ts`
96
+ - `createOrganizationAssignmentJob()`: Create new job record when assignment starts
97
+ - `completeOrganizationAssignmentJob()`: Mark job as completed with statistics
98
+ - `updateOrganizationAssignmentJobMetadata()`: Update job metadata during processing
99
+ - `getOrganizationAssignmentJobsForMappingJob()`: Query jobs by mapping job ID
100
+ - `getOrganizationAssignmentJobsForOrganization()`: Query jobs by organization ID
101
+ - `getPendingOrganizationAssignmentJobs()`: Get incomplete jobs
102
+ - `getOrganizationAssignmentJobById()`: Get specific job by ID
103
+ - `getLatestOrganizationAssignmentJob()`: Get most recent job for mapping+org combo
104
+ - `validateOrganizationAssignmentJobCompletion()`: Check if job is complete
105
+ - `deleteOrganizationAssignmentJob()`: Delete job record
106
+
107
+ - **TypeScript Types**: Added `OrganizationAssignmentJob` and `NewOrganizationAssignmentJob` types
108
+ - **Relations**: Added relations between organization_assignment_jobs ↔ mapping_jobs and organizations
109
+ - **Migration**: Manual migration file `0021_add_organization_assignment_jobs_table.sql`
110
+
111
+ ### Purpose
112
+
113
+ This table provides observability for the `organization_assignments_handler` Lambda (formerly `mapping_job_completion_handler`). Each record tracks:
114
+
115
+ - When an assignment job runs
116
+ - Which organization is being updated
117
+ - How many relationships were removed (old assignments cleared)
118
+ - How many relationships were added (new assignments created)
119
+ - Whether the contributor was created, promoted, or unchanged
120
+ - Any errors that occurred during processing
121
+
122
+ This enables monitoring, debugging, and auditing of the organization assignment process.
123
+
124
+ ## [8.13.0] - 2025-10-06
125
+
126
+ ### Added
127
+
128
+ - **Waitlist Table**: New `public.waitlist` table for capturing email signups
129
+ - `id`: Serial primary key
130
+ - `email`: VARCHAR(255) with regex validation (email format check)
131
+ - `linkedin_public_identifier`: VARCHAR(255) for LinkedIn profile identifier (optional)
132
+ - `created_at`: Timestamp with timezone, auto-set to current time
133
+ - Unique constraint on email to prevent duplicates
134
+ - Email format validation using PostgreSQL regex check constraint
135
+ - Index on email column for fast lookups
136
+
137
+ ## [8.7.0] - 2025-10-02
138
+
139
+ ### 🚀 MAJOR: LinkedIn Schema Migration Complete
140
+
141
+ **Major Enhancement**: Successfully migrated `public.relationship_scores` to `linkedin.relationships` with zero data loss and full backward compatibility.
142
+
143
+ #### Added
144
+
145
+ - **New Schema Structure**: `linkedin.relationships` table with proper LinkedIn-scoped relationships
146
+ - **Enhanced Type Safety**: Updated TypeScript types (`LinkedinRelationship`, `NewLinkedinRelationship`)
147
+ - **Improved Schema Organization**: Relationships properly scoped to LinkedIn platform
148
+ - **Comprehensive Documentation**: Complete migration guide and field migration documentation
149
+
150
+ #### Changed
151
+
152
+ - **BREAKING**: `public.relationship_scores` table migrated to `linkedin.relationships`
153
+ - **Field Names**: Updated relationship table to use `linkedin_account_id_a` and `linkedin_account_id_b`
154
+ - **Schema References**: All Drizzle schema definitions updated to use `linkedinRelationships`
155
+ - **Sync Scripts**: All production-to-dev sync operations updated for new schema
156
+ - **Documentation**: Updated all API examples and schema documentation
157
+
158
+ #### Migration Details
159
+
160
+ - **Data Migration**: Successfully migrated **45,847 relationship records** with zero data loss
161
+ - **Performance**: Optimized migration completed in ~2 minutes vs 20+ minutes initial approach
162
+ - **Foreign Keys**: All constraints properly updated and maintained
163
+ - **Backward Compatibility**: API function names preserved (e.g., `getTopRelationshipScoresForMappingJob`)
164
+
165
+ #### Technical Changes
166
+
167
+ - **Schema Layer**: Updated `schema.ts` with `linkedinRelationships` table definition
168
+ - **Relations**: Updated all Drizzle relations to use correct table references
169
+ - **Imports**: All imports updated from `relationshipScores` to `linkedinRelationships`
170
+ - **Sync Operations**: Updated all prod-to-dev sync scripts to use `linkedin.relationships`
171
+ - **Validation**: Updated all validation and utility scripts
172
+
173
+ #### Files Updated
174
+
175
+ - ✅ **Schema Definition**: `src/lib/schema.ts` with new table structure
176
+ - ✅ **Sync Scripts**: All scripts in `scripts/sync-prod-to-dev/` updated
177
+ - ✅ **Documentation**: `README.md`, `docs/API.md`, `docs/FIELD_MIGRATION_GUIDE.md`
178
+ - ✅ **Migration Guide**: Complete `LINKEDIN_SCHEMA_MIGRATION.md` with step-by-step process
179
+ - ✅ **Lambda Functions**: All application code maintains API compatibility
180
+
181
+ #### Verification
182
+
183
+ - ✅ **Zero Data Loss**: All 45,847 records successfully migrated
184
+ - ✅ **Foreign Key Integrity**: All relationships maintained and working
185
+ - ✅ **API Compatibility**: Existing consumers unaffected by changes
186
+ - ✅ **Performance**: Optimized schema structure with proper indexing
187
+ - ✅ **Documentation**: Complete guides for migration and field changes
188
+
189
+ **Migration Status**: ✅ **COMPLETE SUCCESS** - Production ready with full backward compatibility
190
+
191
+ ## [6.5.4] - 2025-09-24
192
+
193
+ ### Fixed
194
+
195
+ - **CRITICAL FIX**: Fixed `getAllOnDemandMappingJobsForUser()` pagination and data retrieval
196
+ - **ISSUE**: Complex LEFT JOINs were filtering out jobs without complete target profile data
197
+ - **BEFORE**: Only returned 4 jobs out of 22 total (jobs with complete LinkedIn profile data only)
198
+ - **AFTER**: Returns ALL 22 jobs with proper pagination support
199
+ - **SOLUTION**: Refactored to two-step approach:
200
+ 1. Get all on-demand mapping jobs (guaranteed to return all jobs)
201
+ 2. Enrich each job with target profile data (if available)
202
+ - **IMPACT**: Chrome extension now shows all mapping jobs instead of just the ones with complete profiles
203
+ - **PERFORMANCE**: More reliable than complex JOINs, handles missing target data gracefully
204
+ - **PAGINATION**: Fixed limit/offset to work correctly with all jobs
205
+
206
+ ### Changed
207
+
208
+ - **QUERY ARCHITECTURE**: Improved robustness of on-demand mapping job queries
209
+ - Jobs without target LinkedIn profiles now display "Unknown User" until data is available
210
+ - Eliminated data loss from complex JOIN conditions
211
+ - Better error handling for target profile data fetching
212
+ - Maintains backwards compatibility with existing API responses
213
+
214
+ ### Technical Details
215
+
216
+ - Modified `getAllOnDemandMappingJobsForUser()` in `utils/on-demand-mapping-operations.ts`
217
+ - Separated base job fetching from target profile enrichment
218
+ - Added proper TypeScript typing for nullable target profile fields
219
+ - Improved error handling with try/catch for individual target data queries
220
+
221
+ ## [4.25.0] - 2025-09-22
222
+
223
+ ### Changed
224
+
225
+ - **RELATIONSHIP FILTERING**: Updated relationship queries to use latest mapping job filtering
226
+ - Modified `findRelationshipsByLinkedInIdentifier()` to filter by highest `mapping_job_id` instead of `model_version`
227
+ - Updated `findRelationshipsByLinkedInIdentifierPaginated()` to use same filtering logic
228
+ - Ensures that for each person, only relationships from the most recent mapping job are returned
229
+ - Uses PostgreSQL `DISTINCT ON` with `mapping_job_id DESC` ordering for optimal performance
230
+
231
+ ### Added
232
+
233
+ - **NEW FUNCTIONS**: Added convenience functions for latest relationship filtering
234
+ - `findLatestRelationshipsByLinkedInIdentifier()` - Explicit function for latest mapping job filtering
235
+ - `getRelationshipVersionStats()` - Provides insights into relationship data versioning per mapping job
236
+ - **ENHANCED SELECTION**: Added `mappingJobId` to query selections for better debugging and tracking
237
+
238
+ ## [4.24.0] - 2025-09-10
239
+
240
+ ### Added
241
+
242
+ - **VALIDATION**: ACoA identifier validation for `internal_identifier_regular` column
243
+ - Added `validateAcoIdentifier()` function with comprehensive validation rules
244
+ - Added `InvalidAcoIdentifierError` custom error class for clear error messages
245
+ - Validates identifiers must start with "ACoA", be exactly 39 characters, and contain only valid characters
246
+
247
+ ### Changed
248
+
249
+ - **DATABASE CONSTRAINT**: Updated `internal_identifier_regular` column length from 255 to exactly 39 characters
250
+ - **SCHEMA MIGRATION**: Added `chk_internal_identifier_regular_length` constraint to enforce exact 39-character length
251
+ - **QUERY VALIDATION**: Added validation to all functions that set `internal_identifier_regular`:
252
+ - `buildLinkedInAccountValues()` validates when mapping identifiers
253
+ - `upsertLinkedInAccount()` validates incoming ACoA identifiers
254
+ - `createUserAndLinkedInAccountForLinkedIn()` validates both request and provider IDs
255
+
256
+ ### Fixed
257
+
258
+ - **DATA CLEANUP**: Removed 2 duplicate LinkedIn account records with 40-character trailing slashes
259
+ - **MIGRATION COMPATIBILITY**: Resolved "value too long for type character varying(39)" migration errors
260
+
261
+ ### Developer Tools
262
+
263
+ - Added `scripts/check-internal-identifier-regular-issues.ts` for data validation
264
+ - Added `scripts/remove-duplicate-trailing-slash-profiles.ts` for cleanup
265
+ - Added `scripts/test-aco-identifier-validation.ts` with comprehensive test suite
266
+
267
+ ### Migration Notes
268
+
269
+ This version includes database schema changes. The migration:
270
+
271
+ 1. Changes `internal_identifier_regular` column from `varchar(255)` to `varchar(39)`
272
+ 2. Adds check constraint to ensure exactly 39 characters when not null
273
+ 3. All existing data has been validated and cleaned to meet the new requirements
274
+
275
+ ## [4.23.3] - 2025-09-10
276
+
277
+ ### BREAKING CHANGES
278
+
279
+ - **REMOVED**: Complete cache_db support and infrastructure
280
+ - **REMOVED**: All cache-related files, schemas, and configurations
281
+ - **REMOVED**: `cache-db.ts`, `cache-schema.ts`, `drizzle-cache.config.ts`
282
+ - **REMOVED**: `drizzle-cache/` directory with all cache migrations
283
+ - **REMOVED**: Cache-related npm scripts (`cache:*` commands)
284
+ - **REMOVED**: Cache database documentation (`CACHE_DATABASE.md`)
285
+ - **SIMPLIFIED**: `aws-config.ts` to only support main database connections
286
+ - **SIMPLIFIED**: Environment configuration to remove cache database references
287
+
288
+ ### Migration Guide
289
+
290
+ If you were using cache database functionality:
291
+
292
+ 1. Migrate any critical data from `cache_db` to `eggi_main`
293
+ 2. Update any code that imported cache-related exports
294
+ 3. Remove cache-related environment variables from your configuration
295
+ 4. Update database connection logic to use only main database
296
+
297
+ ### Database Architecture
298
+
299
+ The RDS schema now focuses exclusively on the main `eggi_main` database with proper cascade delete chains for:
300
+
301
+ - On-demand mapping jobs → Mapping jobs → Relationship scores + LinkedIn account mappings
302
+ - Simplified database access patterns for better maintainability
303
+
304
+ ## [4.22.15] - 2025-09-09
305
+
306
+ ### Changed
307
+
308
+ - **BREAKING**: Updated `checkLinkedInProfileAvailability` to check ALL completed mapping jobs instead of just on-demand jobs
309
+ - Function now joins `mapping_jobs_linkedin_accounts` with `mapping_jobs` table to verify completion status
310
+ - Only considers mapping jobs with `completedAt` timestamp (fully processed mappings)
311
+ - Improved accuracy of "mapped_before" detection across all mapping job types
312
+ - Enhanced 24-hour deduplication logic based on actual completion time
313
+
314
+ ### Fixed
315
+
316
+ - Fixed issue where availability check only looked at on-demand mapping jobs, missing other types of completed mappings
317
+ - Corrected logic to properly detect when LinkedIn profiles have been successfully mapped by any service
318
+
319
+ ## [4.22.13] - 2025-09-09
320
+
321
+ ### Final Production Release
322
+
323
+ - ✅ **Profile Skills Verification**: Confirmed Lambda correctly creates profile-level skills from Ghost Genius top-level skills array
324
+ - ✅ **End-to-End Testing**: All field extraction working perfectly (profile, education, work experience skills)
325
+ - ✅ **Database Constraints**: All regex and unique constraints verified and working
326
+ - ✅ **Identifier Routing**: ACoA identifiers correctly stored in `internal_identifier_regular` column
327
+ - ✅ **Code Cleanup**: Removed temporary debugging scripts, production-ready codebase
328
+ - ✅ **Complete Field Mapping**: All required fields for Supabase sync properly extracted and stored
329
+ - 🚀 **Ready for Lambda Update**: Package ready for deployment to `get_linkedin_profile` Lambda function
330
+
331
+ ### Technical Details
332
+
333
+ - **Profile Skills**: 20+ skills correctly extracted from Ghost Genius response
334
+ - **Education Skills**: Properly linked to education entries with correct foreign keys
335
+ - **Work Experience Skills**: Correctly associated with work experience entries
336
+ - **Database Integrity**: All constraints enforced at database level
337
+ - **Migration System**: Fully synchronized with Drizzle migrations
338
+
339
+ ## [4.22.12] - 2025-09-09
340
+
341
+ ### Added
342
+
343
+ - **Unique Constraint** - Added unique constraint on `internal_identifier_regular` to prevent duplicate ACoA identifiers across all LinkedIn accounts
344
+ - Comprehensive constraint testing suite for both regex and unique constraints
345
+ - Duplicate detection and cleanup utilities
346
+
347
+ ### Fixed
348
+
349
+ - **Data Cleanup** - Resolved existing duplicate ACoA identifier (John Ciannello profile) by removing the newer duplicate record
350
+ - **Migration System** - Fixed drizzle migration numbering conflicts and ensured proper constraint application through migration 31
351
+ - **Database Integrity** - All LinkedIn identifier constraints now properly enforced at database level
352
+
353
+ ### Technical
354
+
355
+ - Enhanced constraint validation with proper error handling
356
+ - Improved data consistency and prevented race condition duplicates
357
+ - Streamlined migration process with comprehensive testing
358
+
359
+ ## [4.22.11] - 2025-09-09
360
+
361
+ ### Added
362
+
363
+ - **Database Regex Constraints** - Added check constraints to enforce LinkedIn identifier format rules:
364
+ - `internal_identifier` must start with 'ACwA' (for Unipile/authenticated accounts)
365
+ - `internal_identifier_regular` must start with 'ACoA' (for Guest/anonymous accounts)
366
+ - Comprehensive test suite to verify constraint enforcement with invalid data rejection
367
+ - Migration sync verification tools and scripts
368
+
369
+ ### Fixed
370
+
371
+ - **Migration System** - Fixed migration 0 tracking issue and ensured database is fully in sync with migration files (32/32)
372
+ - **Data Integrity** - All existing data validated as compliant with new constraints
373
+ - **Infrastructure** - Lambda rebuilt with latest rds-schema to use new constraints
374
+
375
+ ### Technical
376
+
377
+ - Added WhatsApp to `linkedin_account_type` enum
378
+ - Enhanced database schema validation and error prevention
379
+ - Improved identifier routing reliability and data consistency
380
+
381
+ ## [4.22.10] - 2025-09-08
382
+
383
+ ### Fixed
384
+
385
+ - Verified exports for `createUserAndLinkedInAccountForLinkedIn` and `storeCompleteLinkedInProfile` functions
386
+ - Ensured proper function availability for Lambda consumption
387
+
388
+ ## [4.22.9] - 2025-09-08
389
+
390
+ ### Fixed
391
+
392
+ - **CRITICAL FIX: ACoA identifier routing** - Fixed issue where ACoA identifiers were incorrectly stored in `internal_identifier` instead of `internal_identifier_regular`
393
+ - Removed legacy `handleLinkedInProfileFetch` function and updated Lambda to use proper functions
394
+ - Fixed Ghost Genius identifier routing in `createUserAndLinkedInAccountForLinkedIn` to treat ACoA identifiers as provider responses
395
+ - Updated function signatures to match current implementation
396
+
397
+ ### Removed
398
+
399
+ - Removed all legacy compatibility code for cleaner implementation
400
+ - Removed deprecated `handleLinkedInProfileFetch` function
401
+
402
+ ### Updated
403
+
404
+ - Updated Lambda to use `storeCompleteLinkedInProfile` and `createUserAndLinkedInAccountForLinkedIn` directly
405
+ - Enhanced identifier routing logic to ensure ACoA identifiers from Ghost Genius go to `internal_identifier_regular`
406
+
407
+ ## [4.22.6] - 2025-01-09
408
+
409
+ ### 🔧 LINKEDIN PROFILE DATA EXTRACTION FIXES
410
+
411
+ **Critical Fix**: Resolved missing field extraction and skills insertion issues in LinkedIn profile processing.
412
+
413
+ #### Fixed
414
+
415
+ - **Education Field Extraction**: Fixed missing fields in Ghost Genius to LinkedInProfileData transformation
416
+ - ✅ `description`: Now properly extracted from Ghost Genius education data
417
+ - ✅ `activities_and_societies`: Fixed mapping from Ghost Genius `activites_and_societies` (handles API typo)
418
+ - ✅ `school_linkedin_url`: Now correctly maps from `school.url` field
419
+ - ✅ `school_id`: Properly extracted and validated (excludes URL-formatted IDs)
420
+ - ✅ `grade`: Successfully extracted from Ghost Genius education data
421
+
422
+ - **Work Experience Field Extraction**: Enhanced work experience data mapping
423
+ - ✅ `company_linkedin_url`: Now correctly extracted from `company.url` field
424
+ - ✅ `employment_type`: Properly mapped from Ghost Genius work experience data
425
+
426
+ - **Skills Insertion Bug**: Fixed critical `onConflictDoNothing()` misalignment issue
427
+ - **Education Skills**: Fixed index misalignment between `profileData.education` and `insertedEducation` arrays
428
+ - **Work Experience Skills**: Fixed same index misalignment for work experience skills
429
+ - **Solution**: Query existing records after insertion and match by identifying fields (school+degree, company+position)
430
+
431
+ - **Type Safety**: Updated TypeScript interfaces to prevent compilation errors
432
+ - Added `activites_and_societies` field to Ghost Genius `Education` interface
433
+ - Added `school_linkedin_url` field to `LinkedInProfileData.education` interface (backward compatible with legacy `url` field)
434
+
435
+ #### Added
436
+
437
+ - **Comprehensive Test Suite**: Created `test-linkedin-profile-fetch.ts` script for end-to-end validation
438
+ - **Test Data**: Added `ghost-genius-test-data.ts` with real LinkedIn profile data for testing
439
+ - **NPM Script**: Added `test:profile-fetch` for easy test execution
440
+
441
+ #### Technical Details
442
+
443
+ - **Skills Association Logic**: Replaced unreliable array index mapping with database record matching
444
+ - Education skills now match by `school` and `degree` fields
445
+ - Work experience skills now match by `company` and `position` fields
446
+ - **Database Operations**: Enhanced logging and error handling for profile storage operations
447
+ - **Field Validation**: Improved handling of Ghost Genius API response variations and edge cases
448
+
449
+ #### Verification
450
+
451
+ - ✅ All education fields properly extracted and stored
452
+ - ✅ All work experience fields properly extracted and stored
453
+ - ✅ Education skills correctly associated with education records
454
+ - ✅ Work experience skills correctly associated with work experience records
455
+ - ✅ End-to-end test confirms complete data pipeline functionality
456
+
457
+ ## [4.12.0] - 2025-01-24
458
+
459
+ ### 🎛️ QUERY PARAMETER CONTROL FOR COMPLEMENTARY IDENTIFIERS
460
+
461
+ **Major Enhancement**: Added `complementary_ids` query parameter for fine-grained control over identifier returns.
462
+
463
+ #### Added
464
+
465
+ - **Query Parameter**: `complementary_ids=true/false` for GET and POST endpoints
466
+ - **Database Response Enhancement**: Return both `internal_identifier_regular` and `internal_identifier` fields
467
+ - **Lambda Decision Logic**: Business logic moved to Lambda layer for better separation of concerns
468
+
469
+ #### Behavior
470
+
471
+ - **`complementary_ids=true`** + DB lookup → return complementary identifier when available
472
+ - ACoA* request → return ACwA* identifier (if stored)
473
+ - ACwA* request → return ACoA* identifier (if stored)
474
+ - **`complementary_ids=false`** + DB lookup → return original stored identifier
475
+ - **GET fresh** (cache miss) → parameter ignored, return exact Unipile response
476
+ - **Missing parameter** → defaults to `false` (original behavior)
477
+
478
+ #### Architecture
479
+
480
+ - **Database Layer**: Returns both identifiers, lets Lambda decide
481
+ - **Lambda Layer**: Contains business logic for complementary identifier selection
482
+ - **Clean Response**: Single `provider_id` field, no internal identifier fields exposed
483
+
484
+ ## [4.11.8] - 2025-01-24
485
+
486
+ ### 🔄 COMPLEMENTARY IDENTIFIER LOGIC FOR DB-BASED RESPONSES
487
+
488
+ **Critical Fix**: Corrected complementary identifier logic to return complementary IDs for DB-based responses.
489
+
490
+ #### Fixed
491
+
492
+ - **`getOptimalProviderIdForResponse`**: Now returns **complementary** identifiers instead of preferred ones
493
+ - **ACoA\*** requests → return complementary `internalIdentifier` (ACwA\*) when available
494
+ - **ACwA\*** requests → return complementary `internalIdentifierRegular` (ACoA\*) when available
495
+ - **Lambda POST responses**: After storing data, use `getComprehensiveLinkedinProfile` for consistent complementary logic
496
+ - **Cache hit responses**: Properly return complementary identifiers from stored data
497
+
498
+ #### Behavior
499
+
500
+ - **Cache Miss (GET fresh)**: Returns exact Unipile response (no complementary logic)
501
+ - **Cache Hit (GET cached)**: Returns complementary identifier when available
502
+ - **POST requests**: Store data then return complementary identifier when available
503
+
504
+ #### Expected Results
505
+
506
+ - Request `ACwAADSH2jABexaQDAFqIGS1V8YQzzS3N0OMMlY` → Returns `ACoAADSH2jAB6ogAhfdoxnmNoYpnkHiiMhsBK-0`
507
+ - Request `ACoAADSH2jAB6ogAhfdoxnmNoYpnkHiiMhsBK-0` → Returns `ACwAADSH2jABexaQDAFqIGS1V8YQzzS3N0OMMlY`
508
+
509
+ ## [4.11.7] - 2025-01-24
510
+
511
+ ### 🎯 INTELLIGENT PROVIDER_ID SELECTION FOR CACHE RESPONSES
512
+
513
+ **Enhancement**: Updated `getComprehensiveLinkedinProfile` to intelligently choose provider_id based on request type.
514
+
515
+ #### Added
516
+
517
+ - **`getOptimalProviderIdForResponse`**: Smart provider_id selection logic
518
+ - **ACoA\*** requests → prefer returning `internalIdentifierRegular` (ACoA\* stored), fallback to `internalIdentifier`
519
+ - **ACwA\*** requests → prefer returning `internalIdentifier` (ACwA\* stored), fallback to `internalIdentifierRegular`
520
+ - **Other requests** → return whichever identifier is available
521
+
522
+ #### Fixed
523
+
524
+ - **Cache Response Provider ID**: Now returns the most appropriate identifier based on request type
525
+ - **Missing Field**: Added `internalIdentifierRegular` to comprehensive profile query selection
526
+ - **Request-Response Matching**: ACwA\* requests now get back the stored ACwA\* identifier when available, ACoA\* requests get back ACoA\* identifiers
527
+
528
+ #### Impact
529
+
530
+ - **✅ Proper Complementary Returns**: Cache hits now return the expected identifier format based on request type
531
+ - **✅ Fallback Logic**: When preferred identifier isn't available, falls back to the complementary one
532
+ - **✅ API Consistency**: Maintains consistent provider_id format expectations for different request types
533
+
534
+ ## [4.11.6] - 2025-01-24
535
+
536
+ ### 🔍 COMPLEMENTARY IDENTIFIER CACHE LOOKUP FIX
537
+
538
+ **Critical Fix**: Updated search functions to enable cache hits for complementary identifiers.
539
+
540
+ #### Fixed
541
+
542
+ - **`findLinkedInAccountByLinkedInIdentifier`**: Now searches **ALL** internal identifier fields instead of just the expected field
543
+ - ACwA* requests can now find profiles stored with ACoA* identifiers
544
+ - ACoA* requests can now find profiles stored with ACwA* identifiers
545
+ - **`findUserByLinkedInIdentifier`**: Applied same comprehensive search logic for consistency
546
+ - **Cache Hit Logic**: Fixed issue where complementary identifiers wouldn't match existing cached profiles
547
+
548
+ #### Impact
549
+
550
+ - **✅ Solves Cache Miss Issue**: When requesting `ACwAADSH2jABexaQDAFqIGS1V8YQzzS3N0OMMlY` but database has `ACoAADSH2jAB6ogAhfdoxnmNoYpnkHiiMhsBK-0` stored - now finds the cached profile
551
+ - **✅ Proper Complementary Returns**: Cache hits now return the actual stored identifiers instead of echoing request identifiers
552
+ - **✅ Consistent Search Logic**: All LinkedIn identifier search functions now use the same comprehensive approach
553
+
554
+ ## [4.11.5] - 2025-01-24
555
+
556
+ ### 🎯 IDENTIFIER ROUTING & COMPLEMENTARY ID STORAGE
557
+
558
+ **Enhancement**: Improved identifier mapping and complementary identifier storage for LinkedIn profile operations.
559
+
560
+ #### Changed
561
+
562
+ - **Identifier Routing Logic**: Updated `buildLinkedInAccountValues` to properly handle complementary identifiers
563
+ - **ACoA\*** identifiers (Sales Navigator) → stored in `internal_identifier_regular`
564
+ - **ACwA\*** identifiers (Regular LinkedIn) → stored in `internal_identifier`
565
+ - **Complementary ID Storage**: Enhanced storage logic to preserve both request and response identifiers
566
+ - ACwA request → ACoA response: Both identifiers properly stored in their respective columns
567
+ - ACoA request → ACwA response: Both identifiers properly stored in their respective columns
568
+ - **Search Logic**: Updated `findLinkedInAccountByLinkedInIdentifier` to match new identifier routing
569
+ - ACoA\* identifiers → search in `internal_identifier_regular` field
570
+ - ACwA\* identifiers → search in `internal_identifier` field
571
+ - **Enhanced Logging**: Improved debugging information for identifier mapping decisions
572
+
573
+ #### Benefits
574
+
575
+ - **Data Integrity**: Ensures both complementary identifiers are always stored for future cross-reference
576
+ - **Routing Accuracy**: Proper account type routing based on identifier prefixes
577
+ - **Better Debugging**: Enhanced logging for identifier mapping troubleshooting
578
+
579
+ ## [4.1.0] - 2024-12-31
580
+
581
+ ### 🔐 USER-SPECIFIC SECRETS ARCHITECTURE
582
+
583
+ **Evolution**: Migrated from database-specific to user-specific secrets for better security and access control.
584
+
585
+ #### Changed
586
+
587
+ - **BREAKING**: `MAIN_DB_SECRET_ARN` → `DB_ADMIN_PROXY_MAIN_SECRET_ARN` and `DB_ADMIN_DIRECT_MAIN_SECRET_ARN` (specific connection secrets)
588
+ - **BREAKING**: `CACHE_DB_SECRET_ARN` removed (admin user has access to both databases)
589
+ - **Secret Architecture**: Now organized by database users and connection types:
590
+ - `DB_ADMIN_PROXY_MAIN_SECRET_ARN`: Admin user via RDS Proxy for production
591
+ - `DB_ADMIN_DIRECT_MAIN_SECRET_ARN`: Admin user via direct connection for development
592
+ - `DB_MANTAS_SECRET_ARN`: Limited user with access to `cache_db` only
593
+ - **Infrastructure**: Removed deprecated `main_db` and `cache_db` secrets from AWS
594
+ - **Connection Logic**: Same smart connection selection (direct vs proxy)
595
+
596
+ #### Migration Guide
597
+
598
+ **From v4.0.0 to v4.1.0:**
599
+
600
+ 1. **Update environment variables**:
601
+ - Replace `MAIN_DB_SECRET_ARN` with `DB_ADMIN_PROXY_MAIN_SECRET_ARN` (for production)
602
+ - Add `DB_ADMIN_DIRECT_MAIN_SECRET_ARN` (for development, optional)
603
+ - Remove `CACHE_DB_SECRET_ARN` (admin user covers both databases)
604
+
605
+ 2. **Use environment variables directly**:
606
+ - Set `DB_ADMIN_PROXY_MAIN_SECRET_ARN` environment variable
607
+ - Use `terraform output user_secrets_summary` to get secret ARNs
608
+
609
+ 3. **Architecture benefits**:
610
+ - Better security through user-based access control
611
+ - Simplified secret management
612
+ - Granular permissions per database user
613
+
614
+ ## [4.0.0] - 2024-12-31
615
+
616
+ ### 🚀 BREAKING CHANGES - Smart Database Secret Architecture
617
+
618
+ **Major architectural change**: Replaced fragmented secrets with database-centric smart secrets for better organization and security.
619
+
620
+ #### Added
621
+
622
+ - **Smart Database Secrets**: Self-contained secrets per database with both direct and proxy connection info
623
+ - **Automatic Connection Selection**: Environment variable `USE_DIRECT_CONNECTION` to choose connection type
624
+ - **Database-Specific Secrets**: `MAIN_DB_SECRET_ARN` and `CACHE_DB_SECRET_ARN` replace old secret structure
625
+ - **Connection Type Auto-Detection**: Prefer proxy for applications, direct for admin operations
626
+
627
+ #### Changed
628
+
629
+ - **BREAKING**: `RDS_DIRECT_SECRET_ARN` → `MAIN_DB_SECRET_ARN`
630
+ - **BREAKING**: `RDS_PROXY_SECRET_ARN` → `MAIN_DB_SECRET_ARN` (smart secret contains both)
631
+ - **Secret Structure**: Each database secret now contains:
632
+ ```json
633
+ {
634
+ "username": "eggi_admin",
635
+ "password": "...",
636
+ "database": "eggi_main|cache_db",
637
+ "port": 5432,
638
+ "direct_connection": { ... },
639
+ "proxy_connection": { ... },
640
+ "usage_guide": { ... }
641
+ }
642
+ ```
643
+
644
+ #### Improved
645
+
646
+ - **Simplified Configuration**: One secret per database instead of multiple secrets
647
+ - **Better Documentation**: Self-documenting secrets with usage guides
648
+ - **Consistent Credentials**: Same username/password works for both connection types
649
+ - **Enhanced Security**: Clear separation between databases while maintaining same credentials
650
+
651
+ #### Migration Guide
652
+
653
+ 1. **Environment Variables**:
654
+ - Replace `RDS_DIRECT_SECRET_ARN` with `MAIN_DB_SECRET_ARN`
655
+ - Replace `RDS_PROXY_SECRET_ARN` with `MAIN_DB_SECRET_ARN`
656
+ - Add `CACHE_DB_SECRET_ARN` for cache database access
657
+ - Optional: Set `USE_DIRECT_CONNECTION=true` for admin operations
658
+
659
+ 2. **Secret Structure**:
660
+ - Terraform will create new smart secrets automatically
661
+ - Old secrets can be safely removed after migration
662
+ - Same credentials work for both connection types
663
+
664
+ 3. **Code Changes**:
665
+ - No changes needed if using `getDatabaseUrl()` or `getCredentials()`
666
+ - Package automatically handles smart secret destructuring
667
+
668
+ ## [3.2.5] - 2024-12-30
669
+
670
+ ### Fixed
671
+
672
+ - Fixed duplicate key constraint violations in LinkedIn profile skills processing
673
+ - Added proper UPSERT logic with `.onConflictDoNothing()` in `findOrCreateSkills()`
674
+ - Improved error handling for skills processing operations
675
+
676
+ ### Changed
677
+
678
+ - Updated skills processing to handle idempotent operations correctly
679
+ - Enhanced logging for skills processing workflow
680
+
681
+ ## [3.2.4] - 2024-12-29
682
+
683
+ ### Added
684
+
685
+ - Comprehensive LinkedIn profile processing utilities
686
+ - Work experience skills processing with normalized architecture
687
+ - Enhanced contact information processing
688
+
689
+ ### Fixed
690
+
691
+ - Improved error handling in profile processing workflows
692
+ - Better transaction management for batch operations
693
+
694
+ ## [3.2.3] - 2024-12-28
695
+
696
+ ### Added
697
+
698
+ - Cache database support for conversations and messages
699
+ - Multi-database configuration support
700
+ - Enhanced connection management utilities
701
+
702
+ ### Improved
703
+
704
+ - Better database connection pooling
705
+ - Optimized query performance for large datasets
706
+
707
+ - Same credentials work for both connection types
708
+
709
+ 3. **Code Changes**:
710
+ - No changes needed if using `getDatabaseUrl()` or `getCredentials()`
711
+ - Package automatically handles smart secret destructuring
712
+
713
+ ## [3.2.5] - 2024-12-30
714
+
715
+ ### Fixed
716
+
717
+ - Fixed duplicate key constraint violations in LinkedIn profile skills processing
718
+ - Added proper UPSERT logic with `.onConflictDoNothing()` in `findOrCreateSkills()`
719
+ - Improved error handling for skills processing operations
720
+
721
+ ### Changed
722
+
723
+ - Updated skills processing to handle idempotent operations correctly
724
+ - Enhanced logging for skills processing workflow
725
+
726
+ ## [3.2.4] - 2024-12-29
727
+
728
+ ### Added
729
+
730
+ - Comprehensive LinkedIn profile processing utilities
731
+ - Work experience skills processing with normalized architecture
732
+ - Enhanced contact information processing
733
+
734
+ ### Fixed
735
+
736
+ - Improved error handling in profile processing workflows
737
+ - Better transaction management for batch operations
738
+
739
+ ## [3.2.3] - 2024-12-28
740
+
741
+ ### Added
742
+
743
+ - Cache database support for conversations and messages
744
+ - Multi-database configuration support
745
+ - Enhanced connection management utilities
746
+
747
+ ### Improved
748
+
749
+ - Better database connection pooling
750
+ - Optimized query performance for large datasets