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;