diff --git a/.changeset/fix-agreement-version-sort.md b/.changeset/fix-agreement-version-sort.md new file mode 100644 index 0000000000..251c573d1a --- /dev/null +++ b/.changeset/fix-agreement-version-sort.md @@ -0,0 +1,5 @@ +--- +"adcontextprotocol": patch +--- + +Fix semantic version sorting for agreements. When multiple agreement versions share the same effective date, the system now correctly selects the highest version (e.g., 1.1.1 before 1.1). diff --git a/server/public/admin-agreements.html b/server/public/admin-agreements.html index 630a597bb8..a78eb5f3cd 100644 --- a/server/public/admin-agreements.html +++ b/server/public/admin-agreements.html @@ -284,6 +284,22 @@

Edit Agreement

} } + // Compare semantic versions (e.g., "1.1.1" > "1.1" > "1.0") + function compareVersions(a, b) { + const partsA = a.split('.').map(Number); + const partsB = b.split('.').map(Number); + const maxLen = Math.max(partsA.length, partsB.length); + + for (let i = 0; i < maxLen; i++) { + const numA = partsA[i] || 0; + const numB = partsB[i] || 0; + if (numA !== numB) { + return numB - numA; // Descending order (higher versions first) + } + } + return 0; + } + // Render agreements list function renderAgreementsList() { const listDiv = document.getElementById('agreementsList'); @@ -302,6 +318,11 @@

Edit Agreement

grouped[agreement.agreement_type].push(agreement); }); + // Sort each group by version (descending - newest first) + Object.keys(grouped).forEach(type => { + grouped[type].sort((a, b) => compareVersions(a.version, b.version)); + }); + const formatType = (type) => { const types = { 'terms_of_service': 'Terms of Service', diff --git a/server/src/db/company-db.ts b/server/src/db/company-db.ts index f7e06de3a4..f12bbf8dc2 100644 --- a/server/src/db/company-db.ts +++ b/server/src/db/company-db.ts @@ -231,7 +231,10 @@ export class CompanyDatabase { async getCurrentAgreement(): Promise { const pool = getPool(); const result = await pool.query( - 'SELECT * FROM agreements ORDER BY effective_date DESC LIMIT 1' + `SELECT * FROM agreements + ORDER BY effective_date DESC, + string_to_array(version, '.')::int[] DESC + LIMIT 1` ); return result.rows.length > 0 ? this.mapAgreement(result.rows[0]) : null; } diff --git a/server/src/db/organization-db.ts b/server/src/db/organization-db.ts index d7acd87cde..d23e51578b 100644 --- a/server/src/db/organization-db.ts +++ b/server/src/db/organization-db.ts @@ -176,7 +176,10 @@ export class OrganizationDatabase { async getCurrentAgreement(): Promise { const pool = getPool(); const result = await pool.query( - 'SELECT * FROM agreements ORDER BY effective_date DESC LIMIT 1' + `SELECT * FROM agreements + ORDER BY effective_date DESC, + string_to_array(version, '.')::int[] DESC + LIMIT 1` ); return result.rows[0] || null; } @@ -285,7 +288,11 @@ export class OrganizationDatabase { async getCurrentAgreementByType(type: string): Promise { const pool = getPool(); const result = await pool.query( - 'SELECT * FROM agreements WHERE agreement_type = $1 ORDER BY effective_date DESC LIMIT 1', + `SELECT * FROM agreements + WHERE agreement_type = $1 + ORDER BY effective_date DESC, + string_to_array(version, '.')::int[] DESC + LIMIT 1`, [type] ); return result.rows[0] || null;